Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
GROOVY 2.5+, 3.0
1
HEY HOLA
Name
Mario Garcia
Sigo trabajando en Kaleidos
https://kaleidos.net
2 . 1
ME
Sospechoso de pertenecer al:
Madrid Groovy User Group
Social:
https://twitter.com/marioggar
https://github.com/mariogar...
QUE VENIA A CONTAROS ?
Groovy en numeros
Groovy roadmap 2018 / 2019
Que nos ofrece la version 2.5+
Que nos ofrece la versi...
GROOVY EN NUMEROS
4 . 1
REFERENCIAS
OCI Webminar 23, may 2018 by Paul King
Groovy distribution archive
4 . 2
CONTRIBUTORS
30+ nuevos contributors en los ultimos 16 meses
4 . 3
DESCARGAS
23 millones 2016
50 millones 2017
19 millones solo en el 1er Q de 2018
+ 4 millones de descargas al mes y subien...
ULTIMAS VERSIONES
2.4.15: 2018-09-04
2.5.3: 2018-10-14
2.6.0-alpha-4: 2018-06-26
3.0.0-alpha-3: 2018-06-26
4 . 5
ROADMAP
5 . 1
GROOVY 2.5.X
La 2.5.x ya lleva con nosotros 5 meses (2018-05-30)
Actualizaciones a buen ritmo
2.5.0: mayo
2.5.1: julio
2.5...
GROOVY 2.5.X (II)
Macros
JDK 7 es el minimo
Compatible con JDK9/10 con warnings
5 . 3
GROOVY 2.6, 3.0
Alphas de ambas desde mediados de 2018
Parrot parser (JDK8 syntax 1 - 1 y mucho mas)
2.6
JDK7 (min)
Corta ...
HABLEMOS DE GROOVY 2.5
6
ANNOTATIONS
7 . 1
7 . 2
EN GENERAL
Flexibilidad en antiguas anotaciones
Conversion en Meta anotaciones
Validacion de parametros
Ayuda en la cobert...
EJEMPLOS
@Immutable
@AutoImplement
@AutoFinal
@NamedXXX
@Generated
7 . 4
@IMMUTABLE
No poder modificar los campos de una clase
Si los campos son otras clases…
Comprueba que sean immutables tambie...
@IMMUTABLE (OLD)
package madridgug.immutable
import groovy.transform.Immutable
@Immutable
class Car {
Brand brand (1)
Stri...
@IMMUTABLE (NEW - JAVA.TIME)
package madridgug.immutable
import java.time.LocalTime
import groovy.transform.Immutable
@Imm...
@IMMUTABLE (NEW - DI FRIENDLY)
package madridgug.immutable
import groovy.transform.Canonical
import groovy.transform.Immut...
@IMMUTABLE (DI FRIENDLY - II)
+ 1 vez ⇒ Meta anotacion
package madridgug.immutable
import groovy.transform.*
import groovy...
@IMMUTABLE (DI FRIENDLY - III)
Annotated class
Google Guice Module
package madridgug.immutable
@ImmutableDI
class Security...
@IMMUTABLE (DI FRIENDLY - IV)
given: 'a Google Guice Injector'
Injector di = Guice.createInjector(new GuiceModule())
when:...
@IMMUTABLE (OPTIONAL)
Considerado immutable tambien
package madridgug.immutable
import groovy.transform.Immutable
@Immutab...
@AUTOIMPLEMENT
A veces tenemos que implementar un interface
Pero no queremos / podemos implementarlo entero
7 . 13
@AUTOIMPLEMENT
package madridgug.autoimplement
interface MessageSender {
/**
* Sends a message {@link String}
*/
UUID send...
@AUTOIMPLEMENT
Default
package madridgug.autoimplement
import groovy.util.logging.Slf4j
import groovy.transform.AutoImplem...
@AUTOIMPLEMENT
Throw exceptions
package madridgug.autoimplement
import madridgug.exception.NotEnoughTimePalException
impor...
@AUTOIMPLEMENT
Custom code
package madridgug.autoimplement
import static java.time.LocalDateTime.now
import groovy.util.lo...
@AUTOFINAL
A veces cometemos errores re-asignando una variable
Deberia avisarnos en tiempo de compilacion
7 . 18
@AUTOFINAL
package madridgug.autofinal
import groovy.transform.AutoFinal
class WordProcessor {
@AutoFinal
String reverseWo...
@DELEGATE ENHANCEMENTS
Hasta ahora solo se podia utilizar sobre propiedades de la
clase
7 . 20
@DELEGATE ENHANCEMENTS
Ahora @Delegate se puede usar en getters
package madridgug.delegate
class TennisPlayer {
List<Map> ...
@DELEGATE ENHANCEMENTS
given: 'two players'
def good = new TennisPlayer(name: 'John', wins: [
[name: 'Roland Garros 2014']...
@NAMEDVARIANT
Posibilidad de llamar a un metodo con la instancia del
tipo requerido o …
Descomponiendo la instancia en sus...
@NAMEDVARIANT
package madridgug.namedvariant
class Car {
String brand
String model
Integer hp
}
package madridgug.namedvar...
@NAMEDVARIANT
Pasando una instancia
Car car = new Car(brand: 'ferrari', model: 'F450', hp: 450)
CarProcessor processor = n...
@NAMEDVARIANT
Pasando propiedades
and: 'a processor instance'
CarProcessor processor = new CarProcessor()
when: 'processin...
@NAMEDVARIANT
NamedParam
package madridgug.namedvariant
import java.time.LocalDateTime
import groovy.util.logging.Slf4j
im...
@NAMEDVARIANT
Invocacion
and: 'a processor instance'
AnotherCarProcessor processor = new AnotherCarProcessor()
when: 'proc...
@GENERATED
Concebido para los autores de transformciones AST
Ayuda a las herramientas de cobertura de codigo
Para saber qu...
MACROS
8 . 1
LAS UTILIDADES DE MACROS
ABSTRAEN…
La generacion de nuevo codigo
El filtrado de codigo sobre el que quieres aplicar una
tr...
UTILIDADES
macro {} (generacion)
MacroClass {} (generacion)
@Macro (transformacion)
ASTMatcher (filtrado)
8 . 3
MACRO METHOD
Nos permite crear statements y expressions
De manera mas facil y natural
8 . 4
MACRO METHOD
Este codigo
Deberia contemplar este test
package madridgug.macros.method
class SafeCalls {
@MakeParamSafe
sta...
MACRO METHOD
Como crear la guarda antes del codigo ?
API AST "A pelo"
GeneralUtils para reducirlo
macro {}
8 . 6
MACRO METHOD
API ASTs
GeneralUtils
IfStatement safeGuard = new IfStatement(
new NotExpression(
new VariableExpression(para...
MACRO METHOD
macro {}
1 Las expressiones se interpolan
2 Dentro de codigo plano
VariableExpression paramRef = Utils.getPar...
MACRO METHOD
Mejor caso de uso
BlockStatement getMD5Code(final String propertyName) {
return macro(true) {
java.security.M...
MACROCLASS
Para crear clases y/o metodos con la misma tecnica que
con el macro {} method
8 . 10
MACROCLASS
Creacion de clase
@CompileDynamic
ClassNode buildTemplateClass(ClassNode reference) {
def methodCount = constX(...
MACROCLASS
Creacion de clase
package madridgug.macros.method
@Statistics
class ProcessorWithStatistics {
String name
void ...
MACROCLASS
Creacion de clase
void 'check statistics'() {
given: 'an instance of processor'
ProcessorWithStatistics process...
ASTMATCHER
Clase de utilidad para filtrar, seleccionar nodos que
transformar
Una vez que localizas lo que quieres modifica...
ASTMATCHER
@Override
Expression transform(Expression exp) {
Expression ref = macro { 1 + 1 }
if (ASTMatcher.matches(ref, e...
@MACRO
Transforman aquellas invocaciones a metodos que tienen
el nombre anotado
Parecido a las extensiones
No imports requ...
@MACRO
public class ExampleMacroMethods {
@Macro
public static Expression safe(MacroContext macroContext, MethodCa
return ...
@MACRO
def nullObject = null
assert null == safe(safe(nullObject.hashcode()).toString())
8 . 18
@MACRO
nullObject?.hashcode()?.toString()
8 . 19
HABLEMOS DE GROOVY 3.X
9 . 1
ALINEACION CON JDK9 / 10
9 . 2
PARROT
Renovacion del parser de Groovy
Groovy vuelve a ser un super conjunto de Java
Entre otras cosas… lambdas syntax
9 ....
LAMBDAS
Lambdas
static Integer applyLambdas() {
return Stream
.of(1, 2, 3)
.filter(y -> y % 2 == 0)
.map(y -> y + 1)
.mapT...
LAMBDAS
Lambdas
static Integer applyLambdas2() {
return Stream
.of(1, 2, 3)
.reduce((Integer acc, Integer val) -> {
return...
METHOD REFERENCES
@CompileStatic
static Integer applyMethodReferences(Integer x) {
return Optional
.ofNullable(x)
.map(Fun...
LAMBDAS + CLOSURES + M. REF.
Todo junto
static Integer applyBoth() {
return Stream
.of(1, 2, 3)
.filter { y -> y % 2 == 0 ...
LAMBDAS OTHERS
// Sin parentesis
static Function<Integer, Integer> inc = x -> x + 1
// Con valor por defecto (No existe en...
LAMBDAS OTHERS
Son las lambdas realmente lambdas ?
Con @CompileStatic ⇒ lambdas
Sin @CompileStatic ⇒ closures
9 . 9
LOOPS
En general todos los tipos de loops que se puedan hacer
en Java
Ahora se puede hacer un do / while por ejemplo
9 . 10
LOOPS
Multi asignacion
List<String> returnValues() {
List<String> values = []
for (def (String u, Integer v) = ['bar', 42]...
NUEVOS OPERADORES
Identidad
Elvis
Safe indexing
9 . 12
IDENTIDAD
package madridgug.parrot
import groovy.transform.Immutable
class Identity {
@Immutable
class Person {
String nam...
ELVIS
void newElvis(Integer x) {
x ?= 0 // instead of x ? x : 0
println x + 1
}
9 . 14
SAFE INDEXING
void safeIndexing() {
def numbers = null
println numbers?[10] // will print null
}
9 . 15
OTROS
Default methods en interfaces
!in y !instanceof
9 . 16
@GROOVYDOC
Comentarios accesibles en tiempo de ejecucion
9 . 17
@GROOVYDOC
package madridgug.parrot
class Processor {
/**
* @Groovydoc accesible1 (1)
*/
void process(String word) {
print...
@GROOVYDOC
comments
annotation
String content = Processor
.methods
.find { it.name == 'process' }
.groovydoc
.content
asse...
QUE QUEDA POR CONTAR ?
10 . 1
GROOVY 2.5
@TupleConstructor
Repeated annotations
Anotaciones en mas sitios (JSR-308)
Mejoras en el CliBuilder
with vs tap...
GROOVY 3.X
Mejora en la syntaxis try with resources
10 . 3
GROOVY ECOSYSTEM
11 . 1
BIBLIOTECAS Y FRAMEWORKS
Nombre Version Groovy
Spock 1.2-groovy-2.5 2.5.2
Micronaut 1.0.0-RC2 2.5.1
Geb 2.2 2.4.15
Grails ...
WANNA KNOW MORE ?
https://www.youtube.com/watch?v=ECZVbiFZPwE
12
QUESTIONS & ANSWERS
13
Próxima SlideShare
Cargando en…5
×

Groovy 2.5 and 3.0 (Spanish)

671 visualizaciones

Publicado el

En esta presentacion recorro muchas de las nuevas funcionalidades de la version 2.5 y la proxima 3.0 del lenguage de programacion Groovy.

Publicado en: Tecnología
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Groovy 2.5 and 3.0 (Spanish)

  1. 1. GROOVY 2.5+, 3.0 1
  2. 2. HEY HOLA Name Mario Garcia Sigo trabajando en Kaleidos https://kaleidos.net 2 . 1
  3. 3. ME Sospechoso de pertenecer al: Madrid Groovy User Group Social: https://twitter.com/marioggar https://github.com/mariogarcia 2 . 2
  4. 4. QUE VENIA A CONTAROS ? Groovy en numeros Groovy roadmap 2018 / 2019 Que nos ofrece la version 2.5+ Que nos ofrece la version 3.0 3
  5. 5. GROOVY EN NUMEROS 4 . 1
  6. 6. REFERENCIAS OCI Webminar 23, may 2018 by Paul King Groovy distribution archive 4 . 2
  7. 7. CONTRIBUTORS 30+ nuevos contributors en los ultimos 16 meses 4 . 3
  8. 8. DESCARGAS 23 millones 2016 50 millones 2017 19 millones solo en el 1er Q de 2018 + 4 millones de descargas al mes y subiendo 4 . 4
  9. 9. ULTIMAS VERSIONES 2.4.15: 2018-09-04 2.5.3: 2018-10-14 2.6.0-alpha-4: 2018-06-26 3.0.0-alpha-3: 2018-06-26 4 . 5
  10. 10. ROADMAP 5 . 1
  11. 11. GROOVY 2.5.X La 2.5.x ya lleva con nosotros 5 meses (2018-05-30) Actualizaciones a buen ritmo 2.5.0: mayo 2.5.1: julio 2.5.2: agosto 5 . 2
  12. 12. GROOVY 2.5.X (II) Macros JDK 7 es el minimo Compatible con JDK9/10 con warnings 5 . 3
  13. 13. GROOVY 2.6, 3.0 Alphas de ambas desde mediados de 2018 Parrot parser (JDK8 syntax 1 - 1 y mucho mas) 2.6 JDK7 (min) Corta esperanza de vida 5 . 4
  14. 14. HABLEMOS DE GROOVY 2.5 6
  15. 15. ANNOTATIONS 7 . 1
  16. 16. 7 . 2
  17. 17. EN GENERAL Flexibilidad en antiguas anotaciones Conversion en Meta anotaciones Validacion de parametros Ayuda en la cobertura de codigo 7 . 3
  18. 18. EJEMPLOS @Immutable @AutoImplement @AutoFinal @NamedXXX @Generated 7 . 4
  19. 19. @IMMUTABLE No poder modificar los campos de una clase Si los campos son otras clases… Comprueba que sean immutables tambien O que esten en una lista blanca de clases 7 . 5
  20. 20. @IMMUTABLE (OLD) package madridgug.immutable import groovy.transform.Immutable @Immutable class Car { Brand brand (1) String model Double hp Map<?, String> extra (2) } 7 . 6
  21. 21. @IMMUTABLE (NEW - JAVA.TIME) package madridgug.immutable import java.time.LocalTime import groovy.transform.Immutable @Immutable class Brand { String name LocalTime birthdate (1) } 7 . 7
  22. 22. @IMMUTABLE (NEW - DI FRIENDLY) package madridgug.immutable import groovy.transform.Canonical import groovy.transform.ImmutableBase import groovy.transform.PropertyOptions import groovy.transform.options.ImmutablePropertyHandler @ImmutableBase @Canonical(defaults = false) @PropertyOptions(propertyHandler = ImmutablePropertyHandler) class SecurityConfig { URI provider String key } 7 . 8
  23. 23. @IMMUTABLE (DI FRIENDLY - II) + 1 vez ⇒ Meta anotacion package madridgug.immutable import groovy.transform.* import groovy.transform.options.* @ImmutableBase @TupleConstructor(defaults = false) @PropertyOptions(propertyHandler = ImmutablePropertyHandler) @AnnotationCollector @interface ImmutableDI { } 7 . 9
  24. 24. @IMMUTABLE (DI FRIENDLY - III) Annotated class Google Guice Module package madridgug.immutable @ImmutableDI class SecurityConfig2 { URI provider String key } def ctor = SecurityConfig2.getConstructor(URI, String) bind(SecurityConfig2) .toConstructor(ctor) .in(Scopes.SINGLETON) 7 . 10
  25. 25. @IMMUTABLE (DI FRIENDLY - IV) given: 'a Google Guice Injector' Injector di = Guice.createInjector(new GuiceModule()) when: 'getting the configuration instance' SecurityConfig2 config = di.getInstance(SecurityConfig2) then: 'properties should've been populated properly' config.key == 'key' config.provider == URI.create('https://nowhereprovider.io') when: 'trying to change properties again' config.key = 'another key' then: 'an error will be thrown' thrown(ReadOnlyPropertyException) 7 . 11
  26. 26. @IMMUTABLE (OPTIONAL) Considerado immutable tambien package madridgug.immutable import groovy.transform.Immutable @Immutable class Person { String name Integer age Optional<String> mobile } 7 . 12
  27. 27. @AUTOIMPLEMENT A veces tenemos que implementar un interface Pero no queremos / podemos implementarlo entero 7 . 13
  28. 28. @AUTOIMPLEMENT package madridgug.autoimplement interface MessageSender { /** * Sends a message {@link String} */ UUID sendMessage(String message) /** * Checks whether the message has been received yet or not */ boolean isMessageReceived(UUID messageId) /** * Checks whether the message has been sent yet or not */ Boolean isMessageSent(UUID messageId) } 7 . 14
  29. 29. @AUTOIMPLEMENT Default package madridgug.autoimplement import groovy.util.logging.Slf4j import groovy.transform.AutoImplement @Slf4j @AutoImplement class PartialMessageSender implements MessageSender { @Override UUID sendMessage(String message) { log.info "message: $message" return UUID.randomUUID() } } 7 . 15
  30. 30. @AUTOIMPLEMENT Throw exceptions package madridgug.autoimplement import madridgug.exception.NotEnoughTimePalException import groovy.util.logging.Slf4j import groovy.transform.AutoImplement @Slf4j @AutoImplement(exception = NotEnoughTimePalException) class NoisyMessageSender implements MessageSender { @Override UUID sendMessage(String message) { log.info "message: $message" return UUID.randomUUID() } 7 . 16
  31. 31. @AUTOIMPLEMENT Custom code package madridgug.autoimplement import static java.time.LocalDateTime.now import groovy.util.logging.Slf4j import groovy.transform.AutoImplement @Slf4j @AutoImplement(code = { log.error("Necesito + tiempo ok? Prueba a las: ${now() + 120}") }) class VeryNoisyMessageSender implements MessageSender { } 7 . 17
  32. 32. @AUTOFINAL A veces cometemos errores re-asignando una variable Deberia avisarnos en tiempo de compilacion 7 . 18
  33. 33. @AUTOFINAL package madridgug.autofinal import groovy.transform.AutoFinal class WordProcessor { @AutoFinal String reverseWord(Word word) { // word = new Word(word: 'another') (1) return word.reverse() } Integer size(Word word) { word = new Word(word: 'another') (2) return word.size() } 7 . 19
  34. 34. @DELEGATE ENHANCEMENTS Hasta ahora solo se podia utilizar sobre propiedades de la clase 7 . 20
  35. 35. @DELEGATE ENHANCEMENTS Ahora @Delegate se puede usar en getters package madridgug.delegate class TennisPlayer { List<Map> wins String name @Delegate Integer getWinSize() { return wins.size() } } 7 . 21
  36. 36. @DELEGATE ENHANCEMENTS given: 'two players' def good = new TennisPlayer(name: 'John', wins: [ [name: 'Roland Garros 2014'], [name: 'Roland Garros 2015'], [name: 'Roland Garros 2016'] ]) def bad = new TennisPlayer(name: 'Peter', wins: [ [name: 'Somewhere 2002'] ]) and: 'the good one should be greater than the bad one' good.intValue() > bad.intValue() 7 . 22
  37. 37. @NAMEDVARIANT Posibilidad de llamar a un metodo con la instancia del tipo requerido o … Descomponiendo la instancia en sus diferentes attributos 7 . 23
  38. 38. @NAMEDVARIANT package madridgug.namedvariant class Car { String brand String model Integer hp } package madridgug.namedvariant import groovy.util.logging.Slf4j import groovy.transform.NamedVariant import groovy.transform.NamedDelegate @Slf4j class CarProcessor { @NamedVariant void process(@NamedDelegate Car car) { log.info "processing: ${car.model}" } } 7 . 24
  39. 39. @NAMEDVARIANT Pasando una instancia Car car = new Car(brand: 'ferrari', model: 'F450', hp: 450) CarProcessor processor = new CarProcessor() when: 'processing the car' processor.process(car) 7 . 25
  40. 40. @NAMEDVARIANT Pasando propiedades and: 'a processor instance' CarProcessor processor = new CarProcessor() when: 'processing the car' processor.process(brand: 'ferrari', model: 'F450', hp: 450) 7 . 26
  41. 41. @NAMEDVARIANT NamedParam package madridgug.namedvariant import java.time.LocalDateTime import groovy.util.logging.Slf4j import groovy.transform.* @Slf4j class AnotherCarProcessor { @NamedVariant void process(String user, @NamedParam LocalDateTime now, @NamedDelegate Car car) { log.info "$user ha procesado el modelo ${car.model} el $now" } } 7 . 27
  42. 42. @NAMEDVARIANT Invocacion and: 'a processor instance' AnotherCarProcessor processor = new AnotherCarProcessor() when: 'processing the car' processor.process( 'John Doe', now: LocalDateTime.now(), brand: 'ferrari', model: 'F450', hp: 450, ) 7 . 28
  43. 43. @GENERATED Concebido para los autores de transformciones AST Ayuda a las herramientas de cobertura de codigo Para saber que codigo es generado y cual no Hasta ahora ni JaCoCo ni Cobertura lo tenian facil 7 . 29
  44. 44. MACROS 8 . 1
  45. 45. LAS UTILIDADES DE MACROS ABSTRAEN… La generacion de nuevo codigo El filtrado de codigo sobre el que quieres aplicar una transformacion La transformacion de codigo 8 . 2
  46. 46. UTILIDADES macro {} (generacion) MacroClass {} (generacion) @Macro (transformacion) ASTMatcher (filtrado) 8 . 3
  47. 47. MACRO METHOD Nos permite crear statements y expressions De manera mas facil y natural 8 . 4
  48. 48. MACRO METHOD Este codigo Deberia contemplar este test package madridgug.macros.method class SafeCalls { @MakeParamSafe static Integer inc(Integer a) { // if (!a) { return 1 } return a + 1 } } void 'check unsafe calls'() { expect: 'unsafe calls to return ok' SafeCalls.inc(null) == 1 } 8 . 5
  49. 49. MACRO METHOD Como crear la guarda antes del codigo ? API AST "A pelo" GeneralUtils para reducirlo macro {} 8 . 6
  50. 50. MACRO METHOD API ASTs GeneralUtils IfStatement safeGuard = new IfStatement( new NotExpression( new VariableExpression(paramName) ), new ReturnStatement(new ConstantExpression(1)), new EmptyStatement() ) IfStatement safeGuard = ifS( notX(varX(paramName)), returnS(constX(1)) ) as IfStatement 8 . 7
  51. 51. MACRO METHOD macro {} 1 Las expressiones se interpolan 2 Dentro de codigo plano VariableExpression paramRef = Utils.getParamAsVarX(methodNode) (1) IfStatement safeGuard = macro { if (! $v { paramRef }) { (2) return 1 } } 8 . 8
  52. 52. MACRO METHOD Mejor caso de uso BlockStatement getMD5Code(final String propertyName) { return macro(true) { java.security.MessageDigest.getInstance('MD5') .digest(${propertyName}.getBytes('UTF-8')) .encodeHex() .toString() } } 8 . 9
  53. 53. MACROCLASS Para crear clases y/o metodos con la misma tecnica que con el macro {} method 8 . 10
  54. 54. MACROCLASS Creacion de clase @CompileDynamic ClassNode buildTemplateClass(ClassNode reference) { def methodCount = constX(reference.methods.size()) def fieldCount = constX(reference.fields.size()) return new MacroClass() { class Statistics { java.lang.Integer getMethodCount() { return $v { methodCount } } java.lang.Integer getFieldCount() { return $v { fieldCount } } } } 8 . 11
  55. 55. MACROCLASS Creacion de clase package madridgug.macros.method @Statistics class ProcessorWithStatistics { String name void processX(){} void processY(){} void processZ(){} } 8 . 12
  56. 56. MACROCLASS Creacion de clase void 'check statistics'() { given: 'an instance of processor' ProcessorWithStatistics processor = new ProcessorWithStatistics() expect: 'number of methods' processor.methodCount == 3 and: 'number of fields' processor.fieldCount == 1 } 8 . 13
  57. 57. ASTMATCHER Clase de utilidad para filtrar, seleccionar nodos que transformar Una vez que localizas lo que quieres modificar lo modificas 8 . 14
  58. 58. ASTMATCHER @Override Expression transform(Expression exp) { Expression ref = macro { 1 + 1 } if (ASTMatcher.matches(ref, exp)) { return macro { 3 } } return super.transform(exp) } 8 . 15
  59. 59. @MACRO Transforman aquellas invocaciones a metodos que tienen el nombre anotado Parecido a las extensiones No imports required 8 . 16
  60. 60. @MACRO public class ExampleMacroMethods { @Macro public static Expression safe(MacroContext macroContext, MethodCa return ternaryX( notNullX(callExpression.getObjectExpression()), callExpression, constX(null) ); } ... } 8 . 17
  61. 61. @MACRO def nullObject = null assert null == safe(safe(nullObject.hashcode()).toString()) 8 . 18
  62. 62. @MACRO nullObject?.hashcode()?.toString() 8 . 19
  63. 63. HABLEMOS DE GROOVY 3.X 9 . 1
  64. 64. ALINEACION CON JDK9 / 10 9 . 2
  65. 65. PARROT Renovacion del parser de Groovy Groovy vuelve a ser un super conjunto de Java Entre otras cosas… lambdas syntax 9 . 3
  66. 66. LAMBDAS Lambdas static Integer applyLambdas() { return Stream .of(1, 2, 3) .filter(y -> y % 2 == 0) .map(y -> y + 1) .mapToInt(Integer::intValue) .sum() } 9 . 4
  67. 67. LAMBDAS Lambdas static Integer applyLambdas2() { return Stream .of(1, 2, 3) .reduce((Integer acc, Integer val) -> { return acc + val }).orElse(1) } 9 . 5
  68. 68. METHOD REFERENCES @CompileStatic static Integer applyMethodReferences(Integer x) { return Optional .ofNullable(x) .map(Functions::x2) .map(inc) .orElse(1) } 9 . 6
  69. 69. LAMBDAS + CLOSURES + M. REF. Todo junto static Integer applyBoth() { return Stream .of(1, 2, 3) .filter { y -> y % 2 == 0 } // closure syntax .map( y -> y + 1 ) // lambda syntax .mapToInt(Integer::intValue) // method ref .sum() } 9 . 7
  70. 70. LAMBDAS OTHERS // Sin parentesis static Function<Integer, Integer> inc = x -> x + 1 // Con valor por defecto (No existe en Java) static Function<Integer, Integer> dob = (x = 0) -> x * 2 // Con parentesis static Function<Integer, Integer> tri = (Integer x) -> x * 3 // Con llaves static Function<Integer, Integer> com = (Integer x) -> { x + 4 } 9 . 8
  71. 71. LAMBDAS OTHERS Son las lambdas realmente lambdas ? Con @CompileStatic ⇒ lambdas Sin @CompileStatic ⇒ closures 9 . 9
  72. 72. LOOPS En general todos los tipos de loops que se puedan hacer en Java Ahora se puede hacer un do / while por ejemplo 9 . 10
  73. 73. LOOPS Multi asignacion List<String> returnValues() { List<String> values = [] for (def (String u, Integer v) = ['bar', 42]; v < 45; u++, v++) { values << "$u $v" } return values } 9 . 11
  74. 74. NUEVOS OPERADORES Identidad Elvis Safe indexing 9 . 12
  75. 75. IDENTIDAD package madridgug.parrot import groovy.transform.Immutable class Identity { @Immutable class Person { String name } void checkIdentity(Person left, Person right) { if (left === right) { (1) log.info "es la misma persona" } if (left == right) { (2) log.info "son personas con caracteristicas iguales" } 9 . 13
  76. 76. ELVIS void newElvis(Integer x) { x ?= 0 // instead of x ? x : 0 println x + 1 } 9 . 14
  77. 77. SAFE INDEXING void safeIndexing() { def numbers = null println numbers?[10] // will print null } 9 . 15
  78. 78. OTROS Default methods en interfaces !in y !instanceof 9 . 16
  79. 79. @GROOVYDOC Comentarios accesibles en tiempo de ejecucion 9 . 17
  80. 80. @GROOVYDOC package madridgug.parrot class Processor { /** * @Groovydoc accesible1 (1) */ void process(String word) { println "process: $word" } @Groovydoc('accesible2') (2) void check(String word) { println "check: $word" } } 9 . 18
  81. 81. @GROOVYDOC comments annotation String content = Processor .methods .find { it.name == 'process' } .groovydoc .content assert content == 'accesible1 // <1>' String content = Processor .methods .find { it.name == 'check' } .groovydoc .content assert content == 'accesible2' 9 . 19
  82. 82. QUE QUEDA POR CONTAR ? 10 . 1
  83. 83. GROOVY 2.5 @TupleConstructor Repeated annotations Anotaciones en mas sitios (JSR-308) Mejoras en el CliBuilder with vs tap 10 . 2
  84. 84. GROOVY 3.X Mejora en la syntaxis try with resources 10 . 3
  85. 85. GROOVY ECOSYSTEM 11 . 1
  86. 86. BIBLIOTECAS Y FRAMEWORKS Nombre Version Groovy Spock 1.2-groovy-2.5 2.5.2 Micronaut 1.0.0-RC2 2.5.1 Geb 2.2 2.4.15 Grails 3.3.8 2.4.15 Griffon 2.15.0 2.4.15 11 . 2
  87. 87. WANNA KNOW MORE ? https://www.youtube.com/watch?v=ECZVbiFZPwE 12
  88. 88. QUESTIONS & ANSWERS 13

×