Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
AST – Groovy Transformers:
More than meets the eye!
IVÁN LÓPEZ
@ilopmar
Hello!
I am Iván López
@ilopmar
@madridgug http://greachconf.com
“
The best code is not code at all
1.
A little bit of theory
AST and compilation
▷ Abstract Syntax Tree
▷ AST modified during compilation
▷ Hook into the compiler phases
AST Transformations
▷ Global ▷ Local
2.
Out-of-the-box ASTs
AST transformations categories
▷ Code generation
▷ Class design
▷ Logging improvements
▷ Declarative concurrency
▷ Cloning...
Code generation
@ToString
▷ Human readable toString
▷ Effective Java by Joshua Bloch (item 10)
class User {
String name
Integer age
}
def u = new User(name: 'Iván', age: 35)
println u // User@1d2a54b2
@groovy.transform.ToString
class User {
String name
Integer age
}
def u = new User(name: 'Iván', age: 35)
assert u.toStrin...
@groovy.transform.ToString
class User {
String name
Integer age
}
def u = new User(name: 'Iván', age: 35)
assert u.toStrin...
@ToString
▷ includeNames, excludes, includes, includeSuper,
includeSuperProperties, includeFields, ignoreNulls,
includePac...
@ToString
▷ includeNames, excludes, includes, includeSuper,
includeSuperProperties, includeFields, ignoreNulls,
includePac...
@EqualsAndHashCode
▷ Generate equals and hashCode implementations
▷ Effective Java items 8 & 9
@EqualsAndHashCode
▷ Generate equals and hashCode implementations
▷ Effective Java items 8 & 9
@groovy.transform.EqualsAnd...
int hashCode() {
def _result = HashCodeHelper.initHash()
_result = HashCodeHelper.updateHash(_result, this.name)
_result =...
@EqualsAndHashCode
▷ excludes, includes, callSuper, includeFields, cache,
useCanEqual
@EqualsAndHashCode
▷ excludes, includes, callSuper, includeFields, cache,
useCanEqual
@groovy.transform.EqualsAndHashCode(...
@TupleConstructor
▷ Generate constructors
@TupleConstructor
▷ Generate constructors
@groovy.transform.TupleConstructor
class User {
String name
Integer age
}
@TupleConstructor
▷ Generate constructors
@groovy.transform.TupleConstructor
class User {
String name
Integer age
}
// Def...
@TupleConstructor
▷ Generate constructors
@groovy.transform.TupleConstructor
class User {
String name
Integer age
}
// Def...
@TupleConstructor
▷ Generate constructors
@groovy.transform.TupleConstructor
class User {
String name
Integer age
}
// Def...
@TupleConstructor
▷ excludes, includes, includeFields, includeProperties,
includeSuperFields, includeSuperProperties,
call...
@Canonical
▷ @ToString + @EqualsAndHashCode +
@TupleConstructor
@Canonical
▷ @ToString + @EqualsAndHashCode +
@TupleConstructor
@groovy.transform.Canonical
class User {
String name
Integ...
@Canonical
▷ @ToString + @EqualsAndHashCode +
@TupleConstructor
def u1 = new User(name: 'Iván', age: 35)
assert u1.toStrin...
@Canonical
▷ @ToString + @EqualsAndHashCode +
@TupleConstructor
def u2 = new User('Iván', 35) // @TupleConstructor
assert ...
@Canonical
▷ @ToString + @EqualsAndHashCode +
@TupleConstructor
assert u1 == u2 // @EqualsAndHashCode
assert u1.hashCode()...
@InheritConstructors
▷ Reduce boilerplate code when parent classes
have multiple constructors
▷ Useful when overriding exc...
@groovy.transform.InheritConstructors
class MyException extends Exception {
}
protected MyException(String param0, Throwable param1, boolean param2, boolean param3) {
super(param0, param1, param2, par...
@Lazy
▷ Lazy initialization of fields
▷ Useful when creating expensive resources
▷ Effective Java item 71
class SomeBean {
@Lazy
LinkedList myField
}
class SomeBean {
@Lazy
LinkedList myField
}
public LinkedList getMyField() {
if ($myField != null) {
$myField
} else {
$my...
@Sortable
▷ Comparable interface
▷ compareTo method natural order
▷ N methods returning comparators
▷ Effective Java item ...
@groovy.transform.Sortable
class User {
String name
Integer age
Integer born
}
public int compareTo(User other) {
if (this.is(other)) return 0
Integer value = 0
value = this.name <=> other.name
if (val...
@groovy.transform.Sortable
class User {
String name
Integer age
Integer born
}
def users = [
new User(name: 'Mary', age: 15, born: 2000),
new User(name: 'Peter', age: 44, born: 1970),
new User(name: 'J...
assert users.sort(false, User.comparatorByName())*.name == ['John', 'Mary', 'Peter']
assert users.sort(false, User.compara...
@Sortable
▷ includes, excludes
@groovy.transform.Sortable(excludes = 'age')
class User {
String name
Integer age
Integer b...
@Builder
▷ Create fluent API calls
▷ Multiple building strategies
▷ Multiple configuration options: builder name,
prefix, ...
@groovy.transform.builder.Builder
class User {
String name
Integer age
Integer born
}
@groovy.transform.builder.Builder
class User {
String name
Integer age
Integer born
}
def u = User.builder()
.name('Iván')...
public static class User$UserBuilder extends Object {
private String name
private Integer age
private Integer born
public ...
Class design
@Delegate
▷ Implements delegation design pattern
▷ Delegate calls on object to method on delegated
properties
▷ All public...
import java.time.LocalDate
class Conference {
@groovy.lang.Delegate
LocalDate when
String name
}
import java.time.LocalDate
class Conference {
@groovy.lang.Delegate
LocalDate when
String name
}
def greach = new Conferen...
def greach = new Conference(name: 'Greach', when: LocalDate.of(2015, 04, 10))
def gr8conf = new Conference(name: 'GR8Conf'...
class Conference {
...
public boolean isAfter(ChronoLocalDate param0) {
when.isAfter(param0)
}
public boolean isBefore(Chr...
@Immutable
▷ Create immutable classes
▷ Effective Java item 15
▷ Rules for immutability
@groovy.transform.Immutable
class User {
String name
Integer age
}
def u = new User(name: 'Iván', age: 35)
// This does not compile
// You are not allowed to overwrite
// the final class 'User'.
class Admin extends User {
}
@groo...
@groovy.transform.Immutable
class User {
String name
Integer age
}
def u = new User(name: 'Iván', age: 35)
try {
u.name = ...
@Memoized
▷ Cache the result of a method
@Memoized
▷ Cache the result of a method
@groovy.transform.Memoized
Long fibonacci(Integer n) {
if (n < 2) return 1
else r...
@Memoized
▷ Cache the result of a method
@groovy.transform.Memoized
Long fibonacci(Integer n) {
if (n < 2) return 1
else r...
Logging improvements
@Log, @Log4j, @Log4j2, @Slf4j
▷ Static final field for the logger
@Log, @Log4j, @Log4j2, @Slf4j
@groovy.util.logging.Log4j
class MyClass {
void method() {
log.debug "My debug message"
}
}
...
Declarative concurrency
Declarative concurrency
▷ @Synchronized
▷ @WithReadLock
▷ @WithWriteLock
Cloning and externalizing
Cloning and externalizing
▷ @AutoClone
▷ @AutoExternalize
Safe scripting
Safe scripting
▷ @ThreadInterrupt
▷ @TimedInterrupt
▷ @ConditionalInterrupt
Compiler directives
Compiler directives
▷ @TypeChecked
▷ @CompileStatic
▷ @CompileDynamic
Dependencies handling
@Grab
▷ Grape dependency manager
@Grab
▷ Grape dependency manager
@Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
import o...
@GrabResolver
▷ Grape dependency manager
@Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
...
@GrabExclude
▷ Grape dependency manager
@Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
i...
3.
Summary
“
The best code is not code at all
Thanks!
Any questions?
@ilopmar
lopez.ivan@gmail.com
https://github.com/lmivan
Iván López
http://kcy.me/1zr7q
Greach 2015   AST – Groovy Transformers: More than meets the eye!
Prochain SlideShare
Chargement dans…5
×

Greach 2015 AST – Groovy Transformers: More than meets the eye!

1 669 vues

Publié le

Slides for my Greach 2015 talk: http://greachconf.com/speakers/ivan-lopez-ast-groovy-transformers-more-than-meets-the-eye/

The source code is: https://github.com/lmivan/greach2015

Groovy is a great language with extremely powerful capabilities about compile time meta-programming. Do you know that provides more than 40 AST transformations out-of-the box just to make your life as a developer easier?

In this talk you will learn the most important transformations provided by Groovy. I’ll use a lot of code examples to explain all the concepts.

Publié dans : Technologie
  • DOWNLOAD THE BOOK INTO AVAILABLE FORMAT (New Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THE can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THE is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBOOK .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookBOOK, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, EBOOK, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THE Helped Ignite a Movement,-- Atomic Habits: An Easy &amp; Proven Way to Build Good Habits &amp; Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THE the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THE Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • DOWNLOAD FULL eBOOK INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... 1.DOWNLOAD FULL. PDF eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. doc eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. PDF eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. EPUB eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... 1.DOWNLOAD FULL. doc eBook here { https://tinyurl.com/y3nhqquc } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookeBOOK Crime, eeBOOK Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Greach 2015 AST – Groovy Transformers: More than meets the eye!

  1. 1. AST – Groovy Transformers: More than meets the eye! IVÁN LÓPEZ @ilopmar
  2. 2. Hello! I am Iván López @ilopmar @madridgug http://greachconf.com
  3. 3. “ The best code is not code at all
  4. 4. 1. A little bit of theory
  5. 5. AST and compilation ▷ Abstract Syntax Tree ▷ AST modified during compilation ▷ Hook into the compiler phases
  6. 6. AST Transformations ▷ Global ▷ Local
  7. 7. 2. Out-of-the-box ASTs
  8. 8. AST transformations categories ▷ Code generation ▷ Class design ▷ Logging improvements ▷ Declarative concurrency ▷ Cloning and externalizing ▷ Safe scripting ▷ Compiler directives ▷ Dependencies handling
  9. 9. Code generation
  10. 10. @ToString ▷ Human readable toString ▷ Effective Java by Joshua Bloch (item 10)
  11. 11. class User { String name Integer age } def u = new User(name: 'Iván', age: 35) println u // User@1d2a54b2
  12. 12. @groovy.transform.ToString class User { String name Integer age } def u = new User(name: 'Iván', age: 35) assert u.toString() == 'User(Iván, 35)' class User { String name Integer age } def u = new User(name: 'Iván', age: 35) println u // User@1d2a54b2
  13. 13. @groovy.transform.ToString class User { String name Integer age } def u = new User(name: 'Iván', age: 35) assert u.toString() == 'User(Iván, 35)' String toString() { def _result = new StringBuilder() _result.append('User(') _result.append(this.name) _result.append(', ') _result.append(this.age) _result.append(')') return _result.toString() } class User { String name Integer age } def u = new User(name: 'Iván', age: 35) println u // User@1d2a54b2
  14. 14. @ToString ▷ includeNames, excludes, includes, includeSuper, includeSuperProperties, includeFields, ignoreNulls, includePackage, cache
  15. 15. @ToString ▷ includeNames, excludes, includes, includeSuper, includeSuperProperties, includeFields, ignoreNulls, includePackage, cache @groovy.transform.ToString(includeNames = true, excludes = ['name']) class User { String name Integer age } def u = new User(name: 'Iván', age: 35) assert u.toString() == 'User(age:35)'
  16. 16. @EqualsAndHashCode ▷ Generate equals and hashCode implementations ▷ Effective Java items 8 & 9
  17. 17. @EqualsAndHashCode ▷ Generate equals and hashCode implementations ▷ Effective Java items 8 & 9 @groovy.transform.EqualsAndHashCode class User { String name Integer age } def u1 = new User(name: 'Iván', age: 35) def u2 = new User(name: 'Iván', age: 35) assert u1 == u2 assert u1.hashCode() == u2.hashCode()
  18. 18. int hashCode() { def _result = HashCodeHelper.initHash() _result = HashCodeHelper.updateHash(_result, this.name) _result = HashCodeHelper.updateHash(_result, this.age) return _result } boolean canEqual(Object other) { return other instanceof User } boolean equals(Object other) { if (other == null) { return false } if (this.is(other)) { return true } if (!(other instanceof User)) { return false } User otherTyped = ((other) as User) if (!(otherTyped.canEqual(this))) { return false } if (!(this.getName().is(otherTyped.getName()))) { if (this.getName().is(this) && !(otherTyped.getName().is(otherTyped)) || !(this.getName().is(this)) && otherTyped.getName().is(otherTyped)) return false } else { if (!(this.getName().is(this) && otherTyped.getName().is(otherTyped))) { if (!(this.getName() == otherTyped.getName())) { return false } } } } if (!(this.getAge().is(otherTyped.getAge()))) { if (this.getAge().is(this) && !(otherTyped.getAge().is(otherTyped)) || !(this.getAge().is(this)) && otherTyped.getAge().is(otherTyped)) { return false } else { if (!(this.getAge().is(this) && otherTyped.getAge().is(otherTyped))) { if (!(this.getAge() == otherTyped.getAge())) { return false } } } } return true }
  19. 19. @EqualsAndHashCode ▷ excludes, includes, callSuper, includeFields, cache, useCanEqual
  20. 20. @EqualsAndHashCode ▷ excludes, includes, callSuper, includeFields, cache, useCanEqual @groovy.transform.EqualsAndHashCode(includes = 'name') class User { String name Integer age } def u1 = new User(name: 'Iván', age: 35) def u2 = new User(name: 'Iván', age: 42) assert u1 == u2 assert u1.hashCode() == u2.hashCode()
  21. 21. @TupleConstructor ▷ Generate constructors
  22. 22. @TupleConstructor ▷ Generate constructors @groovy.transform.TupleConstructor class User { String name Integer age }
  23. 23. @TupleConstructor ▷ Generate constructors @groovy.transform.TupleConstructor class User { String name Integer age } // Default map constructor def u1 = new User(name: 'Iván', age: 35)
  24. 24. @TupleConstructor ▷ Generate constructors @groovy.transform.TupleConstructor class User { String name Integer age } // Default map constructor def u1 = new User(name: 'Iván', age: 35) // Generated tuple constructor def u2 = new User('Iván', 35) def u3 = new User('Iván')
  25. 25. @TupleConstructor ▷ Generate constructors @groovy.transform.TupleConstructor class User { String name Integer age } // Default map constructor def u1 = new User(name: 'Iván', age: 35) // Generated tuple constructor def u2 = new User('Iván', 35) def u3 = new User('Iván') User(String name = null, Integer age = null) { this.name = name this.age = age }
  26. 26. @TupleConstructor ▷ excludes, includes, includeFields, includeProperties, includeSuperFields, includeSuperProperties, callSuper, force
  27. 27. @Canonical ▷ @ToString + @EqualsAndHashCode + @TupleConstructor
  28. 28. @Canonical ▷ @ToString + @EqualsAndHashCode + @TupleConstructor @groovy.transform.Canonical class User { String name Integer age }
  29. 29. @Canonical ▷ @ToString + @EqualsAndHashCode + @TupleConstructor def u1 = new User(name: 'Iván', age: 35) assert u1.toString() == 'User(Iván, 35)' // @ToString @groovy.transform.Canonical class User { String name Integer age }
  30. 30. @Canonical ▷ @ToString + @EqualsAndHashCode + @TupleConstructor def u2 = new User('Iván', 35) // @TupleConstructor assert u2.toString() == 'User(Iván, 35)' def u1 = new User(name: 'Iván', age: 35) assert u1.toString() == 'User(Iván, 35)' // @ToString @groovy.transform.Canonical class User { String name Integer age }
  31. 31. @Canonical ▷ @ToString + @EqualsAndHashCode + @TupleConstructor assert u1 == u2 // @EqualsAndHashCode assert u1.hashCode() == u2.hashCode() // @EqualsAndHashCode def u2 = new User('Iván', 35) // @TupleConstructor assert u2.toString() == 'User(Iván, 35)' def u1 = new User(name: 'Iván', age: 35) assert u1.toString() == 'User(Iván, 35)' // @ToString @groovy.transform.Canonical class User { String name Integer age }
  32. 32. @InheritConstructors ▷ Reduce boilerplate code when parent classes have multiple constructors ▷ Useful when overriding exception classes
  33. 33. @groovy.transform.InheritConstructors class MyException extends Exception { }
  34. 34. protected MyException(String param0, Throwable param1, boolean param2, boolean param3) { super(param0, param1, param2, param3) } public MyException(Throwable param0) { super(param0) } public MyException(String param0, Throwable param1) { super(param0, param1) } public MyException(String param0) { super(param0) } public MyException() { super() } @groovy.transform.InheritConstructors class MyException extends Exception { }
  35. 35. @Lazy ▷ Lazy initialization of fields ▷ Useful when creating expensive resources ▷ Effective Java item 71
  36. 36. class SomeBean { @Lazy LinkedList myField }
  37. 37. class SomeBean { @Lazy LinkedList myField } public LinkedList getMyField() { if ($myField != null) { $myField } else { $myField = new LinkedList() } }
  38. 38. @Sortable ▷ Comparable interface ▷ compareTo method natural order ▷ N methods returning comparators ▷ Effective Java item 12
  39. 39. @groovy.transform.Sortable class User { String name Integer age Integer born }
  40. 40. public int compareTo(User other) { if (this.is(other)) return 0 Integer value = 0 value = this.name <=> other.name if (value != 0) return value value = this.age <=> other.age if (value != 0) return value value = this.born <=> other.born if (value != 0) return value return 0 } private static class User$NameComparator extends AbstractComparator<User> { public int compare(User arg0, User arg1) { if (arg0 == arg1) return 0 if (arg0 != null && arg1 == null) return -1 if (arg0 == null && arg1 != null) return 1 return arg0.name <=> arg1.name } } private static class User$AgeComparator extends AbstractComparator<User> { ... } @groovy.transform.Sortable class User { String name Integer age Integer born }
  41. 41. @groovy.transform.Sortable class User { String name Integer age Integer born }
  42. 42. def users = [ new User(name: 'Mary', age: 15, born: 2000), new User(name: 'Peter', age: 44, born: 1970), new User(name: 'John', age: 35, born: 1979), ] @groovy.transform.Sortable class User { String name Integer age Integer born }
  43. 43. assert users.sort(false, User.comparatorByName())*.name == ['John', 'Mary', 'Peter'] assert users.sort(false, User.comparatorByAge())*.born == [2000, 1979, 1970] def users = [ new User(name: 'Mary', age: 15, born: 2000), new User(name: 'Peter', age: 44, born: 1970), new User(name: 'John', age: 35, born: 1979), ] @groovy.transform.Sortable class User { String name Integer age Integer born }
  44. 44. @Sortable ▷ includes, excludes @groovy.transform.Sortable(excludes = 'age') class User { String name Integer age Integer born } def users = [ new User(name: 'Mary', age: 15, born: 2000), new User(name: 'Peter', age: 44, born: 1970), new User(name: 'John', age: 35, born: 1979), ] assert users.sort(false, User.comparatorByName())*.name == ['John', 'Mary', 'Peter'] assert users.sort(false, User.comparatorByAge())*.born == [2000, 1979, 1970]
  45. 45. @Builder ▷ Create fluent API calls ▷ Multiple building strategies ▷ Multiple configuration options: builder name, prefix, excludes, includes,... ▷ Effective Java item 2
  46. 46. @groovy.transform.builder.Builder class User { String name Integer age Integer born }
  47. 47. @groovy.transform.builder.Builder class User { String name Integer age Integer born } def u = User.builder() .name('Iván') .age(35) .born(1979) .build() assert u.name == 'Iván' assert u.age == 35 assert u.born == 1979
  48. 48. public static class User$UserBuilder extends Object { private String name private Integer age private Integer born public User$UserBuilder() { } public User$UserBuilder name(String name) { this.name = name return this } public User$UserBuilder age(Integer age) { this.age = age return this } public User$UserBuilder born(Integer born) { this.born = born return this } public User build() { User _theUser = new User() _theUser.name = name _theUser.age = age _theUser.born = born return _theUser } } @groovy.transform.builder.Builder class User { String name Integer age Integer born } def u = User.builder() .name('Iván') .age(35) .born(1979) .build() assert u.name == 'Iván' assert u.age == 35 assert u.born == 1979
  49. 49. Class design
  50. 50. @Delegate ▷ Implements delegation design pattern ▷ Delegate calls on object to method on delegated properties ▷ All public methods are delegated
  51. 51. import java.time.LocalDate class Conference { @groovy.lang.Delegate LocalDate when String name }
  52. 52. import java.time.LocalDate class Conference { @groovy.lang.Delegate LocalDate when String name } def greach = new Conference(name: 'Greach', when: LocalDate.of(2015, 04, 10)) def gr8conf = new Conference(name: 'GR8Conf' when: LocalDate.of(2015, 06, 02))
  53. 53. def greach = new Conference(name: 'Greach', when: LocalDate.of(2015, 04, 10)) def gr8conf = new Conference(name: 'GR8Conf' when: LocalDate.of(2015, 06, 02)) assert greach.isBefore(gr8conf) import java.time.LocalDate class Conference { @groovy.lang.Delegate LocalDate when String name }
  54. 54. class Conference { ... public boolean isAfter(ChronoLocalDate param0) { when.isAfter(param0) } public boolean isBefore(ChronoLocalDate param0) { when.isBefore(param0) } ... } def greach = new Conference(name: 'Greach', when: LocalDate.of(2015, 04, 10)) def gr8conf = new Conference(name: 'GR8Conf' when: LocalDate.of(2015, 06, 02)) assert greach.isBefore(gr8conf) import java.time.LocalDate class Conference { @groovy.lang.Delegate LocalDate when String name }
  55. 55. @Immutable ▷ Create immutable classes ▷ Effective Java item 15 ▷ Rules for immutability
  56. 56. @groovy.transform.Immutable class User { String name Integer age } def u = new User(name: 'Iván', age: 35)
  57. 57. // This does not compile // You are not allowed to overwrite // the final class 'User'. class Admin extends User { } @groovy.transform.Immutable class User { String name Integer age } def u = new User(name: 'Iván', age: 35)
  58. 58. @groovy.transform.Immutable class User { String name Integer age } def u = new User(name: 'Iván', age: 35) try { u.name = 'John' } catch (ReadOnlyPropertyException e) { println e } // This does not compile // You are not allowed to overwrite // the final class 'User'. class Admin extends User { }
  59. 59. @Memoized ▷ Cache the result of a method
  60. 60. @Memoized ▷ Cache the result of a method @groovy.transform.Memoized Long fibonacci(Integer n) { if (n < 2) return 1 else return fibonacci(n-1) + fibonacci(n-2) } fibonacci(300)
  61. 61. @Memoized ▷ Cache the result of a method @groovy.transform.Memoized Long fibonacci(Integer n) { if (n < 2) return 1 else return fibonacci(n-1) + fibonacci(n-2) } fibonacci(300) @groovy.transform.Memoized User getUserInfo(Long userId) { // Expensive repetitive // network operation }
  62. 62. Logging improvements
  63. 63. @Log, @Log4j, @Log4j2, @Slf4j ▷ Static final field for the logger
  64. 64. @Log, @Log4j, @Log4j2, @Slf4j @groovy.util.logging.Log4j class MyClass { void method() { log.debug "My debug message" } } ▷ Static final field for the logger
  65. 65. Declarative concurrency
  66. 66. Declarative concurrency ▷ @Synchronized ▷ @WithReadLock ▷ @WithWriteLock
  67. 67. Cloning and externalizing
  68. 68. Cloning and externalizing ▷ @AutoClone ▷ @AutoExternalize
  69. 69. Safe scripting
  70. 70. Safe scripting ▷ @ThreadInterrupt ▷ @TimedInterrupt ▷ @ConditionalInterrupt
  71. 71. Compiler directives
  72. 72. Compiler directives ▷ @TypeChecked ▷ @CompileStatic ▷ @CompileDynamic
  73. 73. Dependencies handling
  74. 74. @Grab ▷ Grape dependency manager
  75. 75. @Grab ▷ Grape dependency manager @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate // or @Grab('org.springframework:spring-orm:3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate
  76. 76. @GrabResolver ▷ Grape dependency manager @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate // or @Grab('org.springframework:spring-orm:3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate @GrabResolver(name='restlet', root='http://maven.restlet.org/') @Grab(group='org.restlet', module='org.restlet', version='1.1.6')
  77. 77. @GrabExclude ▷ Grape dependency manager @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate // or @Grab('org.springframework:spring-orm:3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate @GrabResolver(name='restlet', root='http://maven.restlet.org/') @Grab(group='org.restlet', module='org.restlet', version='1.1.6') @Grab('net.sourceforge.htmlunit:htmlunit:2.8') @GrabExclude('xml-apis:xml-apis')
  78. 78. 3. Summary
  79. 79. “ The best code is not code at all
  80. 80. Thanks! Any questions? @ilopmar lopez.ivan@gmail.com https://github.com/lmivan Iván López http://kcy.me/1zr7q

×