• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
 

Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011

on

  • 9,958 views

Update on all the novelties of the recent Groovy 1.8 release, and what's cooking for 1.9.

Update on all the novelties of the recent Groovy 1.8 release, and what's cooking for 1.9.

Statistics

Views

Total Views
9,958
Views on SlideShare
6,979
Embed Views
2,979

Actions

Likes
16
Downloads
133
Comments
2

36 Embeds 2,979

http://www.grails66.com 2611
http://shitmores.blogspot.com 174
http://twitter.com 49
http://it.gilbird.com 21
http://shitmores.blogspot.co.uk 20
http://shitmores.blogspot.de 8
http://shitmores.blogspot.mx 8
url_unknown 8
http://shitmores.blogspot.sg 7
http://shitmores.blogspot.ca 7
http://paper.li 7
http://shitmores.blogspot.nl 5
http://www.theromanos.com.au 5
http://shitmores.blogspot.ie 5
https://twitter.com 4
http://tomromano.id.au 4
http://shitmores.blogspot.com.br 3
http://shitmores.blogspot.fr 3
http://shitmores.blogspot.kr 3
http://shitmores.blogspot.com.au 3
http://a0.twimg.com 3
http://shitmores.blogspot.in 3
http://shitmores.blogspot.com.es 2
http://webcache.googleusercontent.com 2
http://shitmores.blogspot.tw 2
http://shitmores.blogspot.fi 2
http://shitmores.blogspot.se 1
http://www.slideshare.net 1
http://shitmores.blogspot.no 1
http://shitmores.blogspot.dk 1
http://shitmores.blogspot.jp 1
http://shitmores.blogspot.it 1
http://shitmores.blogspot.co.il 1
http://shitmores.blogspot.com.ar 1
http://shitmores.blogspot.pt 1
http://shitmores.blogspot.be 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

12 of 2 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011 Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011 Presentation Transcript

    • Groovy Update What’s new in Groovy 1.8 and what’s coming next! Guillaume Laforge Groovy Project Manager SpringSource / VMwaremercredi 18 mai 2011
    • Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource / VMWare • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more... 2mercredi 18 mai 2011
    • Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource / VMWare • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more... 2mercredi 18 mai 2011
    • Groovy 1.7 3mercredi 18 mai 2011
    • Groovy 1.7 185 3mercredi 18 mai 2011
    • Groovy 1.7 185k 3mercredi 18 mai 2011
    • Groovy 1.7 185k FIRST MONTH AFTER RELEASE 3mercredi 18 mai 2011
    • Groovy 1.7 k 3mercredi 18 mai 2011
    • Groovy 1.7 177k SECOND MONTH AFTER RELEASE 3mercredi 18 mai 2011
    • Groovy 1.7 k 3mercredi 18 mai 2011
    • Groovy 1.7 362k USERS? 3mercredi 18 mai 2011
    • ? TIP OF THEmercredi 18 mai 2011 ICEBERG
    • Agenda •What’s new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations – Miscelanous 5mercredi 18 mai 2011
    • Agenda •What’s new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations – Miscelanous •What’s cooking for Groovy 1.9? – Continued runtime performance improvements – Alignments with JDK 7 •Project Coin (small language changes) •InvokeDynamic 5mercredi 18 mai 2011
    • Command chains expressions 6mercredi 18 mai 2011
    • Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 6mercredi 18 mai 2011
    • Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 6mercredi 18 mai 2011
    • Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences •(or any language, of course) 6mercredi 18 mai 2011
    • Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences •(or any language, of course) 6mercredi 18 mai 2011
    • Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences •(or any language, of course) • Let’s have a look at some examples 6mercredi 18 mai 2011
    • Command chains expressions  turn left  then right  7mercredi 18 mai 2011
    • Command chains expressions Alternation of method names  turn left  then right  7mercredi 18 mai 2011
    • Command chains expressions Alternation of method names  turn left  then right  and parameters (even named ones) 7mercredi 18 mai 2011
    • Command chains expressions  turn left  then right  7mercredi 18 mai 2011
    • Command chains expressions Equivalent to:      (    ).    (     )  turn left  then right  7mercredi 18 mai 2011
    • LookM a! N op are ns, no do ts!mercredi 18 mai 2011
    • Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours 9mercredi 18 mai 2011
    • Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument 9mercredi 18 mai 2011
    • Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments 9mercredi 18 mai 2011
    • Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments Woud call: def take(Map m, Quantity q) 9mercredi 18 mai 2011
    • Command chains expressions Now, even less punctuation! take 2.pills  of  chloroquinine  after  6.hours 10mercredi 18 mai 2011
    • Command chains expressions Now, even less punctuation!     (       ).   (             ).      (       ) take 2.pills  of  chloroquinine  after  6.hours 10mercredi 18 mai 2011
    • Command chains expressions // environment initialization Integer.metaClass.getPills { ‐> delegate } Integer.metaClass.getHours { ‐> delegate }   // variable injection def chloroquinine = /*...*/   { } // implementing the DSL logic def take(n) {     [of: { drug ‐>         [after: { time ‐> /*...*/ }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2.pills of chloroquinine after 6.hours 11mercredi 18 mai 2011
    • Command chains expressions take 2.pills  of  chloroquinine  after  6.hours 12mercredi 18 mai 2011
    • Command chains expressions take 2.pills  of  chloroquinine  after  6.hours ... some dots remain ... 12mercredi 18 mai 2011
    • Command chains expressions We could cheat a bit... take 2  pills of  chloroquinine 6  hours after 13mercredi 18 mai 2011
    • Command chains expressions We could cheat a bit...     ( ).     (  ).             ( ).     (     ) take 2  pills of  chloroquinine 6  hours after 13mercredi 18 mai 2011
    • Cheating is playing with the languagemercredi 18 mai 2011
    • Command chains expressions Still doable without cheating though take 2  pills of  chloroquinine after  6 hours 15mercredi 18 mai 2011
    • Command chains expressions Still doable without cheating though     ( ).     (  ).             (     ). (     ) take 2  pills of  chloroquinine after  6 hours 15mercredi 18 mai 2011
    • Command chains expressions // variable injection def (of, after, hours) = /*...*/   // implementing the DSL logic { } def take(n) {     [pills: { of ‐>         [chloroquinine: { after ‐>             [6: { time ‐> }]         }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2 pills of chloroquinine after 6 hours 16mercredi 18 mai 2011
    • Command chains expressions 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names       (   ).        .    (     ) // possible with an odd number of terms take 3  cookies 17mercredi 18 mai 2011
    • Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names       (   ).        .    (     ) // possible with an odd number of terms take 3  cookies     ( ). 17mercredi 18 mai 2011
    • Runtime perf. improvements • Significant runtime improvements for primitive int operations – classical Fibonacci example x13 faster! – almost as fast as Java • Some direct method calls on this • But there’s more to come! – in particular for all the primitive types • But Jochen «blackdrag» will tell you more on that! 18mercredi 18 mai 2011
    • GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms – actors, fork/join, dataflow, agents, STM... • Václav Pech will cover the details on GPars 19mercredi 18 mai 2011
    • Closure enhancements • Closure annotation parameters • Some more functional flavor – composition – trampoline – memoization • Currying improvements 20mercredi 18 mai 2011
    • Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {         Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {         float number         String unit }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) 21mercredi 18 mai 2011
    • Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {         Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {         float number     P oor-m miss Cont Andr racts an’s G é’s talk!     String unit Don’t }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) 21mercredi 18 mai 2011
    • Closure composition def plus2  = { it + 2 } def times3 = { it * 3 }    { def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 assert times3plus2(4) == plus2(times3(4))    { def plus2times3 = times3 << plus2 assert plus2times3(3) == 15 assert plus2times3(5) == times3(plus2(5))    // reverse composition { assert times3plus2(3) == (times3 >> plus2)(3) 22mercredi 18 mai 2011
    • Closure trampoline 23mercredi 18 mai 2011
    • Closure trampoline def factorial factorial = { int n, BigInteger accu = 1G ‐>        if (n < 2) return accu          factorial.trampoline(n ‐ 1, n * accu) }.trampoline()   assert factorial(1)    == 1 assert factorial(3)    == 1 * 2 * 3 assert factorial(1000) == 402387260... 23mercredi 18 mai 2011
    • Closure memoization 24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() 24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms 24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately 24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms 24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately   24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  24mercredi 18 mai 2011
    • Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  // between 10 and 20 invocations cached def plusAtLeast = { ... }.memoizeBetween(10, 20) 24mercredi 18 mai 2011
    • Currying improvements 25mercredi 18 mai 2011
    • Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     25mercredi 18 mai 2011
    • Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     // currying n‐th parameter def joinWithSeparator =      { one, sep, two ‐> one + sep + two } def joinWithComma =      joinWithSeparator.ncurry(1, , ) assert joinWithComma(a, b) == a, b 25mercredi 18 mai 2011
    • Builtin JSON support • Consuming • Producing • Pretty-printing 26mercredi 18 mai 2011
    • Builtin JSON support import groovy.json.*  def payload = new URL(     "http://github.../json/commits/...").text  def slurper = new JsonSlurper() def doc = slurper.parseText(payload)  doc.commits.message.each { println it } 27mercredi 18 mai 2011
    • Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {         name "Guillaume"     age 33         pets "Hector", "Felix" }  println json.toString() 28mercredi 18 mai 2011
    • Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":33, +      "pets":["Hector","Felix"]}})   29mercredi 18 mai 2011
    • Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":33, +      "pets":["Hector","Felix"]}})   {         "person": {                 "name": "Guillaume",              "age": 33,                 "pets": [                         "Hector",                         "Felix"                 ]         } } 29mercredi 18 mai 2011
    • New AST transformations • @Log • @Canonical – @ToString, • @Field – @EqualsAndHashCode, – @TupleConstructor • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • Controlling the execution of your code • @WithWriteLock – @ThreadInterrupt, – @TimedInterrupt, • @ListenerList – @ConditionalInterrupt 30mercredi 18 mai 2011
    • @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {         Car() {                 log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
    • @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {     Guarded     Car() {         w/ an if         log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
    • @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    Hackerg @Log arten class Car {     certified! Guarded     Car() {         w/ an if         log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
    • @Field • Surprising scoping rules in scripts – variables are local to the run() method – variables aren’t visible in methods •although visually the variable is in a surrounding scope • @Field creates a field in the script class @Field List awe = [1, 2, 3] def awesum() { awe.sum() } assert awesum() == 6 32mercredi 18 mai 2011
    • Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? 33mercredi 18 mai 2011
    • Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify it’s run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code 33mercredi 18 mai 2011
    • Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify it’s run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code 33mercredi 18 mai 2011
    • Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify it’s run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code • Also see compilation customizers later on 33mercredi 18 mai 2011
    • @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) {     // eat lots of CPU } 34mercredi 18 mai 2011
    • @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } 34mercredi 18 mai 2011
    • @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } • Two optional annotation parameters available – checkOnMethodStart (true by default) – applyToAllClasses (true by default) 34mercredi 18 mai 2011
    • @TimedInterrupt @TimedInterrupt(10) import groovy.transform.TimedInterrupt    while (true) {     // eat lots of CPU } • InterruptedException thrown when checks indicate code ran longer than desired • Optional annotation parameters available – same as @ThreadInterrupt – value: for an amount of time duration – unit: for the time duration unit (TimeUnit.SECONDS) 35mercredi 18 mai 2011
    • @ConditionalInterrupt • Specify your own condition to be inserted at the start of method and closure bodies – check for available resources, number of times run, etc. • Leverages the new closure annotation parameter feature of Groovy 1.8 @ConditionalInterrupt({ counter++ > 2 }) import groovy.transform.ConditionalInterrupt import groovy.transform.Field    @Field int counter = 0  100.times {         println executing script method... } 36mercredi 18 mai 2011
    • @ToString • Provides a default toString() method to your types • Available annotation options – includeNames, includeFields, includeSuper, excludes import groovy.transform.ToString    @ToString class Person {         String name         int age }    println new Person(name: Pete, age: 15) // => Person(Pete, 15) 37mercredi 18 mai 2011
    • @EqualsAndHashCode • Provides default implementations for equals() and hashCode() methods import groovy.transform.EqualsAndHashCode    @EqualsAndHashCode class Coord {         int x, y }    def c1 = new Coord(x: 20, y: 5) def c2 = new Coord(x: 20, y: 5)    assert c1 == c2 assert c1.hashCode() == c2.hashCode() 38mercredi 18 mai 2011
    • @TupleConstructor • Provides a «classical» constructor with all properties • Several annotation parameter options available import groovy.transform.TupleConstructor    @TupleConstructor  class Person {         String name         int age }    def m = new Person(Marion, 3)         assert m.name == Marion assert m.age  == 3 39mercredi 18 mai 2011
    • @Canonical • One annotation to rule them all! – @Canonical mixes together •@ToString •@EqualsAndHashCode •@TupleConstructor • You can customize behavior by combining @Canonical and one of the other annotations 40mercredi 18 mai 2011
    • @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated class CustomException extends Exception {     CustomException()                        { super()       }     CustomException(String msg)              { super(msg)    }     CustomException(String msg, Throwable t) { super(msg, t) }     CustomException(Throwable t)             { super(t)      } } 41mercredi 18 mai 2011
    • @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated import groovy.transform.* @InheritConstructors class CustomException extends Exception {     CustomException()                        { super()       }     CustomException(String msg)              { super(msg)    }     CustomException(String msg, Throwable t) { super(msg, t) }     CustomException(Throwable t)             { super(t)      } } 41mercredi 18 mai 2011
    • @WithReadLock, @WithWriteLock import groovy.transform.*    class ResourceProvider {         private final Map<String, String> data = new HashMap<>()       @WithReadLock         String getResource(String key) {                 return data.get(key)         }            @WithWriteLock         void refresh() {                 //reload the resources into memory         } } 42mercredi 18 mai 2011
    • @WithReadLock, @WithWriteLock import groovy.transform.*    class ResourceProvider {         private final Map<String, String> data = new HashMap<>()   {     @WithReadLock         String getResource(String key) {                 return data.get(key)         }        {     @WithWriteLock         void refresh() {                 //reload the resources into memory         } } 42mercredi 18 mai 2011
    • Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion 43mercredi 18 mai 2011
    • Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers – ImportCustomizer – SecureASTCustomizer – ASTTransformationCustomizer • But you can implement your own 44mercredi 18 mai 2011
    • Imports customizer def configuration = new CompilerConfiguration()   def custo = new ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)    def result = new GroovyShell(configuration)     .evaluate(" cos PI/3 ") 45mercredi 18 mai 2011
    • Applying an AST transformation def configuration = new CompilerConfiguration() configuration.addCompilationCustomizers(     new ASTTransformationCustomizer(Log))    new GroovyShell(configuration).evaluate("""     class Car {                 Car() {                         log.info Car constructed                 }         }          log.info Constructing a car         def c = new Car() """) 46mercredi 18 mai 2011
    • Secure AST customizer Idea: Implement an «arithmetic shell» Being able control what a user script is allowed to do: only arithmetic expressions • Let’s setup our environment – some imports – an import customizer to import java.lang.Math.* – prepare a secure AST customizer import org.codehaus.groovy.control.customizers.* import org.codehaus.groovy.control.* import static org.codehaus.groovy.syntax.Types.*   def imports = new ImportCustomizer().addStaticStars(java.lang.Math) def secure = new SecureASTCustomizer() ... 47mercredi 18 mai 2011
    • Secure AST customizer ... secure.with { // disallow closure creation closuresAllowed = false  // disallow method definitions methodDefinitionAllowed = false    // empty white list => forbid imports importsWhitelist = []  staticImportsWhitelist = [] // only allow the java.lang.Math.* static import staticStarImportsWhitelist = [java.lang.Math ... 48mercredi 18 mai 2011
    • Secure AST customizer ... // language tokens allowed tokensWhitelist = [ PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, PLUS_PLUS,  MINUS_MINUS, COMPARE_EQUAL, COMPARE_NOT_EQUAL,  COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL,  COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL ]   // types allowed to be used (including primitive types) constantTypesClassesWhiteList = [ Integer, Float, Long, Double, BigDecimal,  Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE ]   // classes who are allowed to be receivers of method calls receiversClassesWhiteList = [  Math, Integer, Float, Double, Long, BigDecimal ] } ... 49mercredi 18 mai 2011
    • Secure AST customizer • Ready to evaluate our arithmetic expressions! ... def config = new CompilerConfiguration() config.addCompilationCustomizers(imports, secure) def shell = new GroovyShell(config)   shell.evaluate cos(PI/3) • But the following would have failed: shell.evaluate System.exit(0) 50mercredi 18 mai 2011
    • Slashy and dollar slashy strings • Slashy strings are now multiline – particularly handy for multi-line regexs • Dollar slashy string notation introduced – a multiline GString with different escaping rules def (name, date) = ["Guillaume", "May, 17th"] def dollarSlashy = $/         Hello $name, today were ${date}     $ dollar‐sign         $$ dollar‐sign          backslash         / slash        $/ slash /$  51mercredi 18 mai 2011
    • New GDK methods 52mercredi 18 mai 2011
    • New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   52mercredi 18 mai 2011
    • New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   52mercredi 18 mai 2011
    • New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   // min/max for maps with closures def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == dddd assert map.min { it.value }.value == 1   52mercredi 18 mai 2011
    • New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   // min/max for maps with closures def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == dddd assert map.min { it.value }.value == 1   // map withDefault() def words = "one two two three three three".split() def freq = [:].withDefault { k ‐> 0 } words.each { freq[it] += 1 } 52mercredi 18 mai 2011
    • (G)String to Enum coercion enum Color {         red, green, blue }  53mercredi 18 mai 2011
    • (G)String to Enum coercion enum Color {         red, green, blue }    53mercredi 18 mai 2011
    • (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    53mercredi 18 mai 2011
    • (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    53mercredi 18 mai 2011
    • (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    // with GStrings too def g = "${green}" as Color 53mercredi 18 mai 2011
    • What’s cookingmercredi 18 mai 2011 for 1.9?
    • Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Rewritten Antlr 3 grammar (GSoC) • Eclipse compiler to replace the joint compiler? • What else? Your call! 55mercredi 18 mai 2011
    • Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Rewritten Antlr 3 grammar (GSoC) • Eclipse compiler to replace the joint compiler? • What else? Your call! 55mercredi 18 mai 2011
    • Binary literals • We had decimal, octal and hexadecimal notations for number literals • We can now use binary representations too int x = 0b10101111 assert x == 175   byte aByte = 0b00100001 assert aByte == 33   int anInt = 0b1010000101000101 assert anInt == 41285 56mercredi 18 mai 2011
    • Underscore in literals • We can now also add underscores in number literals for more readability long creditCardNumber = 1234_5678_9012_3456L long socialSecurityNumbers = 999_99_9999L float monetaryAmount = 12_345_132.12 long hexBytes = 0xFF_EC_DE_5E long hexWords = 0xFFEC_DE5E long maxLong = 0x7fff_ffff_ffff_ffffL long alsoMaxLong = 9_223_372_036_854_775_807L long bytes = 0b11010010_01101001_10010100_10010010 57mercredi 18 mai 2011
    • Multicatch • One block for multiple exception caught – rather than duplicating the block try {     /* ... */ } catch(IOException | NullPointerException e) {     /* one block to treat 2 exceptions */ } 58mercredi 18 mai 2011
    • Summary ROCK! 59mercredi 18 mai 2011
    • Thank you! e aforg pment ume L Develo Guilla Groovy om He ad of e@ gmail.c glaforg rge Email: @glafo : Twitter 60mercredi 18 mai 2011
    • Image credits • Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg • Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2 • Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg • Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg • Cheating: http://fr.academic.ru/pictures/frwiki/67/Cheating.JPG • Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/ • Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg • Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg • Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg • Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg 61mercredi 18 mai 2011