eclipsecon09 introduction to groovy
DESCRIPTION
Eclipsecon09 Introduction to GroovyTRANSCRIPT
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Introduction to Groovy
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.02
Agenda
• What is Groovy• From Java to Groovy• Java-like features• Not-Java features• Unique features• Eclipse & Groovy
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
What is Groovy?
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.04
http://www.flickr.com/photos/teagrrl/78941282/
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
From Java to Groovy
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.06
HelloWorld in Javapublic class HelloWorld { String name;
public void setName(String name) { this.name = name; } public String getName(){ return name; }
public String greet() { return "Hello "+ name; }
public static void main(String args[]){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.out.println( helloWorld.greet() ); }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.07
HelloWorld in Groovypublic class HelloWorld { String name;
public void setName(String name) { this.name = name; } public String getName(){ return name; }
public String greet() { return "Hello "+ name; }
public static void main(String args[]){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.out.println( helloWorld.greet() ); }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.08
Step 1: Let’s get rid of the noisepublicpublic class HelloWorld { String name;;
publicpublic void setName(String name) { this.name = name;; } publicpublic String getName(){ return name;; }
publicpublic String greet() { return "Hello "+ name;; }
publicpublic static void main(String args[]){ HelloWorld helloWorld = new HelloWorld();; helloWorld.setName("Groovy");; System.out.println( helloWorld.greet() );; }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.09
Step 1 - Resultsclass HelloWorld { String name
void setName(String name) { this.name = name } String getName(){ return name }
String greet() { return "Hello "+ name }
static void main(String args[]){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") System.out.println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.010
Step 2: let’s get rid of boilerplateclass HelloWorld { String name
voidvoid setName(String name) setName(String name) { this.name = name }{ this.name = name } String getName(){ return name }String getName(){ return name }
String greet() { return "Hello "+ name }
static void main(String args[]String args[]){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") System.out.System.out.println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.011
Step 2 - Resultsclass HelloWorld { String name
String greet() { return "Hello "+ name }
static void main( args ){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.012
Step 3: Introduce dynamic typesclass HelloWorld { String name
StringString greet() { return "Hello "+ name }
static voidvoid main( args ){ HelloWorldHelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.013
Step 3 - Resultsclass HelloWorld { String name
def greet() { return "Hello "+ name }
static def main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.014
Step 4: Use variable interpolationclass HelloWorld { String name
def greet(){ return "Hello ""Hello "+ name+ name }
static def main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.015
Step 4 - Resultsclass HelloWorld { String name
def greet(){ return "Hello ${name}" }
static def main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.016
Step 5: Let’s get rid of more keywordsclass HelloWorld { String name
def greet(){ returnreturn "Hello ${name}" }
static defdef main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.017
Step 5 - Resultsclass HelloWorld { String name
def greet(){ "Hello ${name}" }
static main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.018
Step 6: POJOs on steroidsclass HelloWorld { String name
def greet(){ "Hello ${name}" }
static main( args ){ defdef helloWorld = helloWorld = newnew HelloWorld() HelloWorld() helloWorld.setName(helloWorld.setName("Groovy""Groovy")) println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.019
Step 6 - Resultsclass HelloWorld { String name
def greet(){ "Hello ${name}" }
static main( args ){ def helloWorld = new HelloWorld(name:"Groovy") // helloWorld.setName("Groovy") // helloWorld.name = "Groovy" // helloWorld["name"] = "Groovy" println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.020
Step 7: Groovy supports scriptsclass HelloWorld { String name
def greet(){ "Hello ${name}" }
static static main( args ){main( args ){ defdef helloWorld = helloWorld = newnew HelloWorld(name HelloWorld(name::""Groovy"Groovy"))
println helloWorld.greet()println helloWorld.greet() }}}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.021
Step 7 - Results
class HelloWorld {
String name
def greet() { "Hello $name" }
}
def helloWorld = new HelloWorld(name:"Groovy")
println helloWorld.greet()
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.022
We came from here…public class HelloWorld { String name;
public void setName(String name) { this.name = name; } public String getName(){ return name; }
public String greet() { return "Hello "+ name; }
public static void main(String args[]){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") System.err.println( helloWorld.greet() ) }}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.023
… to here
class HelloWorld {
String name
def greet() { "Hello $name" }
}
def helloWorld = new HelloWorld(name:"Groovy")
println helloWorld.greet()
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.024
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Java-like FeaturesClose to home
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.026
Java -like features
• A Java class is a Groovy class, a Groovy class is a Java class
• Full JDK5 support: annotations, generics, varargs, enums, enhanced for loop (this requires JRE5)
• 98% of Java code is valid Groovy code
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.027
Varargs in actionclass Calculator { def addAllGroovy( Object[] args ){ int total = 0 for( i in args ) { total += i } total } def addAllJava( int... args ){ int total = 0 for( i in args ) { total += i } total }}
Calculator c = new Calculator()assert c.addAllGroovy(1,2,3,4,5) == 15assert c.addAllJava(1,2,3,4,5) == 15
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.028
Scott Davis' 1st mantra:
Java is Groovy, Groovy is Java
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Not-Java FeaturesExplore the Neighborhood
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.030
Assorted goodies
• Default parameter values as in PHP• Named parameters as in Ruby (reuse the Map trick of
default POGO constructor)• Operator overloading, using a naming convention, for
example
plus()+
leftShift()<<
getAt() / putAt()[ ]
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.031
Closures
• Closures can be seen as reusable blocks of code, you may have seen them in JavaScript and Ruby among other languages.
• Closures substitute inner classes in almost all use cases.
• Groovy allows type coercion of a Closure into a one-method interface
• A closure will have a default parameter named it if you do not define one.
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.032
Examples of closuresdef greet = { name -> println “Hello $name” }greet( “Groovy” )// prints Hello Groovy
def greet = { println “Hello $it” }greet( “Groovy” )// prints Hello Groovy
def iCanHaveTypedParametersToo = { int x, int y -> println “coordinates are ($x,$y)”}
def myActionListener = { event -> // do something cool with event} as ActionListener
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.033
With closures comes currying
• Currying is a programming technique that transforms a function into another while fixing one or more input values (think constants).
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.034
Currying in action// a closure with 3 parameters, the third one is optional// as it defines a default valuedef getSlope = { x, y, b = 0 -> println "x:${x} y:${y} b:${b}" (y - b) / x}
assert 1 == getSlope( 2, 2 )def getSlopeX = getSlope.curry(5)assert 1 == getSlopeX(5)assert 0 == getSlopeX(2.5,2.5)// prints// x:2 y:2 b:0// x:5 y:5 b:0// x:5 y:2.5 b:2.5
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.035
Iterators everywhere
• Like in Ruby you may use iterators in almost any context, Groovy will figure out what to do in each case
• Iterators harness the power of closures, all iterators accept a closure as parameter.
• Iterators relieve you of the burden of looping constructs
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.036
Iterators in actiondef printIt = { println it }// 3 ways to iterate from 1 to 5[1,2,3,4,5].each printIt1.upto 5, printIt(1..5).each printIt
// compare to a regular loopfor( i in [1,2,3,4,5] ) printIt(i)// same thing but use a Rangefor( i in (1..5) ) printIt(i)
[1,2,3,4,5].eachWithIndex { v, i -> println "list[$i] => $v" }// list[0] => 1// list[1] => 2// list[2] => 3// list[3] => 4// list[4] => 5
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.037
Scott Davis' 2nd mantra:
Groovy is Java and Groovy is NOT Java
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Unique FeaturesSpace out!
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.039
The as keyword
• Used for “Groovy casting”, convert a value of typeA into a value of typeB
def intarray = [1,2,3] as int[ ]
• Used to coerce a closure into an implementation of single method interface.
• Used to coerce a Map into an implementation of an interface, abstract and/or concrete class.
• Used to create aliases on imports
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.040
Some examples of asimport javax.swing.table.DefaultTableCellRenderer as DTCR
def myActionListener = { event -> // do something cool with event} as ActionListener
def renderer = [ getTableCellRendererComponent: { t, v, s, f, r, c -> // cool renderer code goes here }] as DTCR
// note that this technique is like creating objects in// JavaScript with JSON format// it also circumvents the fact that Groovy can’t create// inner classes (yet)
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.041
New operators
• ?: (elvis) - a refinement over the ternary operator
• ?. Safe dereference – navigate an object graph without worrying on NPEs
• <=> (spaceship) – compares two values
• * (spread) – “explode” the contents of a list or array
• *. (spread-dot) – apply a method call to every element of a list or array
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.042
Traversing object graphs
• GPath is to objects what XPath is to XML.
• *. and ?. come in handy in many situations
• Because POGOs accept dot and bracket notation for property access its very easy to write GPath expressions.
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.043
Sample GPath expressionsclass Person { String name int id}
def persons = [ new Person( name: 'Duke', id: 1 ), [name: 'Tux', id: 2] as Person]
assert [1,2] == persons.idassert ['Duke','Tux'] == persons*.getName()assert null == persons[2]?.nameassert 'Duke' == persons[0].name ?: 'Groovy'assert 'Groovy' == persons[2]?.name ?: 'Groovy'
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.044
MetaProgramming
• You can add methods and properties to any object at runtime.
• You can intercept calls to method invocations and/or property access (similar to doing AOP but without the hassle).
• This means Groovy offers a similar concept to Ruby’s open classes, Groovy even extends final classes as String and Integer with new methods (we call it GDK).
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.045
A simple example using categories
class Pouncer { static pounce( Integer self ){ def s = “Boing!" 1.upto(self-1) { s += " boing!" } s + "!" }}
use( Pouncer ){ assert 3.pounce() == “Boing! boing! boing!"}
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.046
Same example using MetaClassesInteger.metaClass.pounce << { -> def s = “Boing!" delegate.upto(delegate-1) { s += " boing!" } s + "!“}
assert 3.pounce() == “Boing! boing! boing!"
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.047
More options in Groovy 1.6!
• Compile time metaprogramming via AST transformations
• Runtime mixins
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.048
Scott Davis says:
Groovy is what the Java language would look like had it been written in the 21st century
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Eclipse & Groovy
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.050
Eclipse Plugin
• Allows you to edit, compile and run groovy scripts and classes.
• Syntax coloring• Autocompletion• Groovy nature
• Great support from Eclipse +3.2 series
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.051
How to install
1. Go to Help -> Software Updates -> Find and Install
2. Configure a new update sitehttp://dist.codehaus.org/groovy/distributions/update/
3. Follow the wizard instructions
4. Restart Eclipse. You are now ready to start Groovying!
Introduction to Groovy | © 2009 by «Andres Almiray»; made available under the EPL v1.052
Resources
• Groovy Language, guides, examples http://groovy.codehaus.org
• Groovy Eclipse Plugin http://groovy.codehaus.org/Eclipse+Plugin
• Groovy Related News http://aboutgroovy.com http://groovyblogs.org http://groovy.dzone.com
• My Groovy/Java/Swing blog http://jroller.com/aalmiray http://twitter.com/aalmiray
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Q&A
© 2009 by «Andres Almiray»; made available under the EPL v1.0 | 03/25/2009
Thank you!