1. for Developers
by Leonard Axelsson (@xlson)
1
Thursday, June 17, 2010
2. SweGUG
Leonard Axelsson
• Groovy user since 2006
• Co-Founder of SweGUG
–Swedish Groovy User Group
• Speaker at GTUG, Agical Geeknight, JFokus,
SweGUG
• Developer/Consultant at Qbranch Stockholm
2
Thursday, June 17, 2010
3. SweGUG
Agenda
• Overview and obligatory Hello World
• Syntax Overview
• Tips and Trix
3
Thursday, June 17, 2010
4. SweGUG
Groovy Overview
• Originated in 2003
• Under the Apache License
• Grammar derived from Java 1.5
4
Thursday, June 17, 2010
5. SweGUG
Groovy Overview
• Dynamic language
–Inspired by Python, Ruby and Smalltalk
• Object Oriented
• Easy to learn for Java devs
–Supports Java style code out of the box
• Scriptable
• Embeddable
5
Thursday, June 17, 2010
6. SweGUG
Dynamic Language
• No compile-time checking
– int i = “Hello” throws exception at runtime
• Ducktyping
– def keyword allows you to care about what the object
does, not what it is
• Supports custom DSLs
new DateDSL().last.day.in.december( 2009 )
6
Thursday, June 17, 2010
7. SweGUG
Gotchas
• == uses equals()
–not object identity
–is() used for identity comparission
• return keyword is optional
• Methods and classes are public by default
• All exceptions are unchecked exceptions
• There are no primitives
7
Thursday, June 17, 2010
8. SweGUG
The obligatory Hello World
8
Thursday, June 17, 2010
9. SweGUG
How many in here know Groovy?
9
Thursday, June 17, 2010
10. SweGUG
Groovy can be coded the “Java”
way. So basically all of you!
10
Thursday, June 17, 2010
11. SweGUG
HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
11
Thursday, June 17, 2010
12. SweGUG
HelloWorld.groovy
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
12
Thursday, June 17, 2010
13. SweGUG
Removing ...
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
13
Thursday, June 17, 2010
14. SweGUG
Removing ...
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!")
}
}
14
Thursday, June 17, 2010
15. SweGUG
Removing ...
class HelloWorld {
public static void main(String[] args) {
println("Hello World!")
}
}
15
Thursday, June 17, 2010
17. SweGUG
This is it
println "Hello World!"
17
Thursday, June 17, 2010
18. SweGUG
Feature Overview
• Properties
–dynamic getters and setters
• Closures
–reusable blocks of code
• Meta Object Protocol
–rewrite behaviour at runtime
• Many additions to the JDK
18
Thursday, June 17, 2010
23. SweGUG
Plain Old Groovy Objects
23
Thursday, June 17, 2010
24. SweGUG
POGO’s
• Properties
–getters and setters are created automatically
• Named Parameters
–clarifies intent
class Person {
String name
String lastname
}
def anders = new Person(name: 'Anders', lastname: 'Andersson')
assert anders.getName() == 'Anders'
// Anders gets married and changes his lastname
anders.setLastname("Sundstedt")
assert anders.lastname == "Sundstedt"
24
Thursday, June 17, 2010
25. SweGUG
POGO’s
• Getters and setters can be overridden
class Person {
def name
def lastname
String setLastname(String lastname) {
this.lastname = lastname.reverse()
}
}
def anders = new Person(name: 'Anders', lastname: 'Andersson')
// Anders does a strange change of his lastname
anders.lastname = "Sundstedt"
assert anders.lastname == "tdetsdnuS"
25
Thursday, June 17, 2010
26. SweGUG
Built in syntax for lists and maps
26
Thursday, June 17, 2010
27. SweGUG
Lists
List syntax:
def names = ['Leonard', 'Anna', 'Anders']
assert names instanceof List
assert names.size() == 3
assert names[0] == 'Leonard'
27
Thursday, June 17, 2010
29. SweGUG
each, find and findAll
class Person {
String name
String lastname
boolean male
}
def ages = [new Person(name: 'Bo', lastname: 'Olsson', male: true),
new Person(name: 'Gunn', lastname: 'Bertilsson', male: false),
new Person(name: 'Britt', lastname: 'Olsson', male: false)]
// Print all names
ages.each { println "$it.name $it.lastname" }
// Find one male
assert ages.find{ person -> person.male }.name == 'Bo'
// or find all females
assert ages.findAll{ Person p -> !p.male }.size() == 2
29
Thursday, June 17, 2010
30. SweGUG
Power Asserts
• New in Groovy 1.7
// Will throw an assertion error
def getNum() { 5 }
assert (1 + 100) == num + 77
Output:
Assertion failed:
assert (1 + 100) == num + 77
| | | |
101 | 5 82
false
at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:378)
at ...
30
Thursday, June 17, 2010
31. SweGUG
Method not found?
• Better feedback in Groovy 1.7
// Will throw a MissingMethodException (no beginsWith method)
def carType = "BMW M3"
if(carType.beginsWith('Volvo')) {
println "It's a Volvo!"
}
Output:
groovy.lang.MissingMethodException: No signature of method: java.lang.String.beginsWith() is applicable for argument types:
(java.lang.String) values: [Volvo]
Possible solutions: endsWith(java.lang.String), startsWith(java.lang.String)
at ...
31
Thursday, June 17, 2010
32. SweGUG
@Grab and grape
• Dependency management using Apache Ivy
–Uses Maven Central
• grape commandline tool
–Adds dependencies to Groovys global classpath
• @Grab annotation
–Great for scripting
32
Thursday, June 17, 2010
33. SweGUG
@Grab and GPars
@Grab(group='org.codehaus.gpars', module='gpars', version='0.10')
import groovyx.gpars.GParsExecutorsPool
def importProcessingData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ,18, 19, 20]
time('Parallel execution') {
GParsExecutorsPool.withPool {
importProcessingData.eachParallel { data ->
// Insert arbitrary heavy operation here
sleep 200
}
}
}
time('Linear execution') {
importProcessingData.each {
// Insert arbitrary heavy operation here
sleep 200
}
}
Output (executed on dual-‐core machine):
Parallel execution desc, 1449 ms.{
def time(String took: task)
Linear execution took: 4006 Date().time
def startTime = new ms.
def result = task()
def executionTime = new Date().time - startTime
println "$desc took: $executionTime ms."
result
}
33
Thursday, June 17, 2010