Transcript
Page 1: What makes groovy groovy   codeurs en seine - 2013 - light size

© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.

Guillaume Laforge @glaforge !

What makes Groovy groovy?

Page 2: What makes groovy groovy   codeurs en seine - 2013 - light size

Guillaume Laforge

Groovy project leadat .

@glaforgehttp://glaforge.appspot.com

Page 3: What makes groovy groovy   codeurs en seine - 2013 - light size

Les Cast Codeurs

Page 4: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 5: What makes groovy groovy   codeurs en seine - 2013 - light size

The Groovy vision

Part 1

Page 6: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 7: What makes groovy groovy   codeurs en seine - 2013 - light size

Simplify the life of (Java) developers

Page 8: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 9: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 10: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 11: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 12: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 13: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 14: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 15: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 16: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Page 17: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Fit for Domain-Specific Languages

Page 18: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Fit for Domain-Specific Languages

Most seamless integration & interoperability wih java!

Page 19: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 20: What makes groovy groovy   codeurs en seine - 2013 - light size

It’s so easy to learn!

Page 21: What makes groovy groovy   codeurs en seine - 2013 - light size

It’s so easy to learn!

Groovy as a Java superset

Page 22: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 23: What makes groovy groovy   codeurs en seine - 2013 - light size

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

Page 24: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 25: What makes groovy groovy   codeurs en seine - 2013 - light size

As safe and fast as Java with static type checking & compilation

Page 26: What makes groovy groovy   codeurs en seine - 2013 - light size

As safe and fast as Java with static type checking & compilation

Page 27: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 28: What makes groovy groovy   codeurs en seine - 2013 - light size

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}

!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!rocks!"!!!!!!!!}!!!!}}

Page 29: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 30: What makes groovy groovy   codeurs en seine - 2013 - light size

move!forward!at!3.km/h

Expressive, Concise, Readable

Page 31: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 32: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 33: What makes groovy groovy   codeurs en seine - 2013 - light size

@RestControllerclass!App!{!!!!@RequestMapping("/")!!!!String!home()!{!"Hello!World!"!}}

Speaking of conciseness...A full Spring app in the span of a tweet!

Page 34: What makes groovy groovy   codeurs en seine - 2013 - light size

Serv

ices

Tech

nolo

gy

IoT

Fina

ncia

l

Inte

rnet

Who’s using Groovy?

• Netflix• LinkedIn• Google

• Crédit Suisse• JPMorgan• Fanny Mae• Mutual of Omaha• Hypoport

• Energy Transfer• National Cancer Inst.• IRSN

• European Patent Office

• Amadeus

• SmartThings• Carriots

20

Page 35: What makes groovy groovy   codeurs en seine - 2013 - light size

Cool Groovy gems

Part 2

Page 36: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 37: What makes groovy groovy   codeurs en seine - 2013 - light size

Most Java code is also valid Groovy code!

Page 38: What makes groovy groovy   codeurs en seine - 2013 - light size

Any Java developer is a Groovy developer!

Most Java code is also valid Groovy code!

Page 39: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 40: What makes groovy groovy   codeurs en seine - 2013 - light size

Flat learning curve

Page 41: What makes groovy groovy   codeurs en seine - 2013 - light size

Flat learning curve

Easy to learn

Page 42: What makes groovy groovy   codeurs en seine - 2013 - light size

Scripts versus Classes

24

public!class!Main!{!!!!public!static!void!main(String[]!args)!{!!!!!!!!System.out.println("Hello");!!!!}}

vs

Page 43: What makes groovy groovy   codeurs en seine - 2013 - light size

Scripts versus Classes

24

public!class!Main!{!!!!public!static!void!main(String[]!args)!{!!!!!!!!System.out.println("Hello");!!!!}}

println!"Hello"

vs

Page 44: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

Page 45: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

Semicolons

Page 46: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

Page 47: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword

Page 48: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword public keyword

Page 49: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword public keyword

Typing!

Page 50: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

26

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Page 51: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

26

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Semicolons

Page 52: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

27

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Page 53: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

28

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Page 54: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

28

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Parentheses

Page 55: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

29

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 56: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

29

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

return keyword

Page 57: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

30

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 58: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

30

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

public keyword

Page 59: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

31

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 60: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

31

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

optional typing

Page 61: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

32

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 62: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

32

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

handy println shortcut

Page 63: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

33

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 64: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

33

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

verbose Java properties!

Page 65: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

34

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 66: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

34

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Property notation

Page 67: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

35

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.owner!!!!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 68: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

35

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.owner!!!!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Named argument constructor

Page 69: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

36

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Page 70: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

36

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Interpolated strings!(aka GStrings)

Page 71: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

37

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!${name},!I!am!${owner}"!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Page 72: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

37

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!${name},!I!am!${owner}"!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Let’s reformat that mess of whitespace!

Page 73: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

Page 74: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Page 75: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

Page 76: What makes groovy groovy   codeurs en seine - 2013 - light size

Native syntax constructs

• Closures

• Lists

• Maps

• Regular expressions

• Ranges

39

Page 77: What makes groovy groovy   codeurs en seine - 2013 - light size

Closures

• Functions as first-class citizen of the language

40

Page 78: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

Page 79: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definition

Page 80: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definitionAppend an element

(operator overloading)

Page 81: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definitionAppend an element

(operator overloading)

Functional-style map / filter / reduce

with closures

Page 82: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Page 83: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Page 84: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Indexed access

Page 85: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Indexed accessProperty notation access

Page 86: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

Page 87: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

Pattern

Page 88: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Page 89: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Find

Page 90: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Find

Nice way to decompose the matched regions

Page 91: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Page 92: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Page 93: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Page 94: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Reverse range

Page 95: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Reverse range

Negative index count from the end

Page 96: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Page 97: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Plain java.lang.String

Page 98: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Plain java.lang.String

Multiline string with expression interpolation

Page 99: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

Page 100: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

0.8999999999999999

Page 101: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

0.8999999999999999

Page 102: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

Page 103: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

1

Page 104: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

1

Page 105: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

Page 106: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

One of the reasons why micro-benchmarks sometimes showed

Groovy to be slow...

Page 107: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

One of the reasons why micro-benchmarks sometimes showed

Groovy to be slow...

But you can use doubles & floats for performance, with ‘d’ or ‘f ’ suffixes or with explicit type

Page 108: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 109: What makes groovy groovy   codeurs en seine - 2013 - light size

Powerful switch / case

on steroids

Page 110: What makes groovy groovy   codeurs en seine - 2013 - light size

Powerful switch / case

on steroids

switch(obj)!{!!!!case!123:!!!!!!!!!!!!!!!!!!"number!123";!!!!!!!!break!!!!case!"abc":!!!!!!!!!!!!!!!!"string!abc";!!!!!!!!break!!!!case!String:!!!!!!!!!!!!!!!"is!a!string";!!!!!!!break!!!!case![1,!2,!3]:!!!!!!!!!!!!"contained!in!list";!break!!!!case!~/.*o+.*/:!!!!!!!!!!!!"match!the!regex";!!!break!!!!case!{!it.isUpperCase()!}:!"closure!criteria";!!break****default:!"unknown"}

Page 111: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Page 112: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument

Page 113: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument Named argument

Page 114: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument Named argument

Calls:move(Map m, Object)

Page 115: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

Page 116: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

move!forward!at!3.km/h

Page 117: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

move!forward!at!3.km/h

Actually equivalent to:move(forward).at(3.getKm().div(h))

Page 118: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments and command chains

52

check!that:!vodka!tastes!good

Page 119: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments and command chains

52

check!that:!vodka!tastes!good

Will call:check(that: vodka).tastes(good)

Page 120: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Page 121: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »

Page 122: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Page 123: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Method returning a list

Page 124: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Method returning a list

Destructuring

Page 125: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Page 126: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Method signature convention: getAt(int)

Page 127: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Method signature convention: getAt(int)

Transparent destructuring

Page 128: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Page 129: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Page 130: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Closure blocks delimiting the structure

Page 131: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Closure blocks delimiting the structure

Attributes

Page 132: What makes groovy groovy   codeurs en seine - 2013 - light size

Power asserts

56

def!(a,!b,!c)!=![20,!30,!40]

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1

Page 133: What makes groovy groovy   codeurs en seine - 2013 - light size

Power asserts

56

def!(a,!b,!c)!=![20,!30,!40]

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1

Assertion!failed:!

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1!!!!!!!|!|!!|!|!!!!|!!!!|!!!!|!|!|!!!|!!!!!!!|!580|!29!!!58!!!false|!|!60!!61!!!!!!!20!!!30!!!!!!!!!!!!!!!|!40!!!!!!!!!!!!!!!!!!!!!!!!!!!!!120

! at!script1.run(script1t.groovy:4)

Page 134: What makes groovy groovy   codeurs en seine - 2013 - light size

Null handling

• Groovy provides a more descriptive NullPointerException than Java

• Safe navigation with ?.

57

Page 135: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 136: What makes groovy groovy   codeurs en seine - 2013 - light size

The Truth, the Groovy Truth!

Page 137: What makes groovy groovy   codeurs en seine - 2013 - light size

The Truth, the Groovy Truth!

And what if I could customize the truth?

Page 138: What makes groovy groovy   codeurs en seine - 2013 - light size

?:

Page 139: What makes groovy groovy   codeurs en seine - 2013 - light size

The Elvis operator!

?:

Page 140: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

Page 141: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

Page 142: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!y

Page 143: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!y

Page 144: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!y

Page 145: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!y

Page 146: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y

Page 147: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Page 148: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Good old ternary operator

Page 149: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Good old ternary operatorElvis!

Page 150: What makes groovy groovy   codeurs en seine - 2013 - light size

AST transformations

• Abstract Syntax Tree– in memory representation of your program

before being compiled into bytecode

• AST transformation == process of transforming the AST of a program before it’s compiled

• Macro-like compiler hook!

61

Page 151: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Code generation

– @ToString, @EqualsAndHashCode, @Canonical, @TupleConstructor, @InheritConstructors, @Category, @IndexedProperty, @Lazy, @Newify

• Class design

– @Delegate, @Immutable, @Memoized, @Singleton, @Mixin

• Logging

– @Log, @Log4j, @Log4j2, @Slf4j

62

Page 152: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Safer scripting

– @ConditionalInterrupt, @ThreadInterrupt, @TimedInterupt

• Compiler directives

– @Field, @PackageScope, @AnnotationCollector, @DelegatesTo, @TypeChecked, @CompileStatic, @CompileDynamic

• Swing patterns

– @Bindable, @ListenerList, @Vetoable

63

Page 153: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Dependencies handling

– @Grab, @GrabConfig, @GrabExclude, @GrabResolver

• Test assistance

– @NotYetImplemented, @ASTTest

64

Page 154: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• Implement immutability by the book

– final class– tuple-style constructor– private final backing fields– defensive copying of collections– equals() and hashCode() methods– toString() method– ...

65

Page 155: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• Implement immutability by the book

– final class– tuple-style constructor– private final backing fields– defensive copying of collections– equals() and hashCode() methods– toString() method– ...

65

Can be error-prone to write immutable classes oneself !

Page 156: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Page 157: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Damn verbose

Java!

Page 158: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Damn verbose

Java!

Although it’s also a valid Groovy program!

Page 159: What makes groovy groovy   codeurs en seine - 2013 - light size

@Immutable

67

import!groovy.transform.*

@Immutableclass!Person!{!!!!String!name!!!!int!age}

Page 160: What makes groovy groovy   codeurs en seine - 2013 - light size

Memoization

• Cache the result of previous invocations of closures or methods with the same set of argument values

68

import!groovy.transform.*

@Memoizedlong!fib(long!n)!{!!!!if!(n!==!0)!0!!!!else!if!(n!==!1)!1!!!!else!fib(n!c!1)!+!fib(n!c!2)}

println!fib(40)

Page 161: What makes groovy groovy   codeurs en seine - 2013 - light size

Memoization

• Cache the result of previous invocations of closures or methods with the same set of argument values

68

import!groovy.transform.*

@Memoizedlong!fib(long!n)!{!!!!if!(n!==!0)!0!!!!else!if!(n!==!1)!1!!!!else!fib(n!c!1)!+!fib(n!c!2)}

println!fib(40)

Best applied to side-effect free

functions

Page 162: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 163: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

Page 164: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

Page 165: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

More concise, more readable code

Page 166: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

More concise, more readable code

Less stuff to maintain and worry about

Page 167: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

Page 168: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

You can even extend the static type checker!

Page 169: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

You can even extend the static type checker!

Type check DSLs or dynamic features!

Page 170: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• What is type checked can also be compiled statically with @CompileStatic

– generate the same bytecode as javac

– same performance as Java

71

Page 171: What makes groovy groovy   codeurs en seine - 2013 - light size

Static compilation performance

72

Fibonacci Pi (π) quadrature

Binarytrees

Java

Staticcompilation

Primitive optimizations

No prim.optimizations

191 ms 97 ms 3.6 s

197 ms 101 ms 4.3 s

360 ms 111 ms 23.7 s

2590 ms 3220 ms 50.0 s1.7

1.8

2.x

Page 172: What makes groovy groovy   codeurs en seine - 2013 - light size

Superb community!

Part 3

Page 173: What makes groovy groovy   codeurs en seine - 2013 - light size

A blossomingEcosystem

Page 174: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 175: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 176: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 177: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 178: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM

Page 179: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 180: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM

Page 181: What makes groovy groovy   codeurs en seine - 2013 - light size

GVMGROOVYENVIRONMENT

MANAGER

Page 182: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM: Groovy enVironment Manager

• The new kid on the block– http://gvmtool.net/ — @gvmtool

• Manage parallel versions of the various ecosystem projects

• Supports...– Groovy, Grails, Griffon, Gradle, Vert.x, Spring Boot

• On Linux, MacOS, Cygwin, Solaris, FreeBSD81

Page 183: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 184: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

Page 185: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

...the Spock testing framework

Page 186: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

...the Spock testing framework

Page 187: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

Page 188: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Page 189: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Page 190: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Page 191: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Expression to be asserted

Page 192: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Expression to be assertedCute data-

driven tests!

Page 193: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 194: What makes groovy groovy   codeurs en seine - 2013 - light size

@GrabResolver("https://oss.jfrog.org/artifactory/repo")@Grab("org.ratpackcframework:ratpackcgroovy:0.9.0cSNAPSHOT")import!static!org.ratpackframework.groovy.RatpackScript.ratpackimport!static!org.ratpackframework.groovy.Template.groovyTemplate

ratpack!{!!!!handlers!{!!!!!!!!get!{!!!!!!!!!!!!response.send!"Welcome!"!!!!!!!!}

!!!!!!!!get("date")!{!!!!!!!!!!!!render!groovyTemplate("date.html")!!!!!!!!}

!!!!!!!!assets!"public"!!!!}}

Page 195: What makes groovy groovy   codeurs en seine - 2013 - light size

@GrabResolver("https://oss.jfrog.org/artifactory/repo")@Grab("org.ratpackcframework:ratpackcgroovy:0.9.0cSNAPSHOT")import!static!org.ratpackframework.groovy.RatpackScript.ratpackimport!static!org.ratpackframework.groovy.Template.groovyTemplate

ratpack!{!!!!handlers!{!!!!!!!!get!{!!!!!!!!!!!!response.send!"Welcome!"!!!!!!!!}

!!!!!!!!get("date")!{!!!!!!!!!!!!render!groovyTemplate("date.html")!!!!!!!!}

!!!!!!!!assets!"public"!!!!}}

Lightweight Netty-based web app toolkit

Page 196: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb

• Browser automation solution

• WebDriver + jQuery selectors + Groovy

• Handy for– scripting, scraping, automation...– functional / web / acceptance testing

• when integrated with JUnit, TestNG or Spock

85

Page 197: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Page 198: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Page 199: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Page 200: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Page 201: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Submit the form

Page 202: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Submit the form

In the admin section, yeah!

Page 203: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

Page 204: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

Page 205: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

BDD style: given/when/then

Page 206: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

BDD style: given/when/then

Wait for slow loading pages

Page 207: What makes groovy groovy   codeurs en seine - 2013 - light size

Summary

Part 4

Page 208: What makes groovy groovy   codeurs en seine - 2013 - light size

Java’s best friend

• Java derived syntax– Flat learning curve– Easy to learn

• But goes beyond Java– Concise, expressive, readable– Fit for Domain-Specific Languages

• Seamless & transparent Java integration– Mix and match Groovy and Java classes (joint compil.)– No language barrier to cross

89

Page 209: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy’s nature

• Object oriented dynamic language...

• But...– as type safe as you want it — static type checking

– as fast as you need it — static compilation– as functional as you make it — closures...

90

Page 210: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy use cases

• Scripting tasks, build automation

• Extension points for customizing/configuring apps

• Business languages & Domain-Specific Languages

• Full blown apps

– for desktop with Griffon– for the web with Grails, Ratpack, Gaelyk– for web reactive programming with reactor

91


Top Related