57
© 2008 Andres Almiray; disponible bajo CC-SA 2.5 Introducción a Groovy

Introduccion A Groovy

Embed Size (px)

DESCRIPTION

Presentación introductoria a Groovy en la primera reunión de la comunidad Springhispano.org

Citation preview

Page 1: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Introducción a Groovy

Page 2: Introduccion A Groovy

2© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Acerca del presentador

Desarrollador Java desde 1996 Fan de Groovy desde 2006 dado que a veces Java

estorbaba Miembro del equipo Groovy desde Agosto 2007 Fundador de proyectos como JideBuilder,

GraphicsBuilder, WingSBuilder, Grapplet y Json-lib

Page 3: Introduccion A Groovy

3© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Agenda

Qué es Groovy? De Java a Groovy Características I (cerca de casa) Características II (explorando el vecindario) Características III (al infinito y mas allá!) Groovy & Spring

Page 4: Introduccion A Groovy

4© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Que es Groovy?

Groovy es un lenguage ágil y dinámico para la Máquina Virtual de Java

Basado en los conceptos base del lenguage Java, incluye características inspiradas en otros lenguages como Python, Ruby y Smalltalk.

Habilita características de programación modernas con una curva de aprendizaje prácticamente plana para desarrolladores Java

Soporta Lenguages de Dominio Específico y otras carcaterísticas de syntaxis corta

Page 5: Introduccion A Groovy

5© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Que es Groovy?

Simplifica el ciclo de pruebas dado que soporta pruebas unitarias y mocking desde el inicio.

Se integra sin problemas con cualquier objecto y/o librería Java existentes

Compila directamente a código byte (igual que Java) puede ser usado virtualmente en cualquier lugar donde Java puede serlo también

Page 6: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

De Java a Groovy

Page 7: Introduccion A Groovy

7© 2008 Andres Almiray; disponible bajo CC-SA 2.5

HolaMundo en Java

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() ) }}

Page 8: Introduccion A Groovy

8© 2008 Andres Almiray; disponible bajo CC-SA 2.5

HolaMundo en Groovy

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() ) }}

Page 9: Introduccion A Groovy

9© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 1: Adios a lo obvio

Toda clase, método, campo en Groovy tiene acceso público a menos de que se especifique lo contrario

';' es opcional al final de línea en la mayoría de los casos

Page 10: Introduccion A Groovy

10© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 1: Resultado

class 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.err.println( helloWorld.greet() ) }}

Page 11: Introduccion A Groovy

11© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 2: Adios a lo ceremonioso

Neal Ford proclama que el debate estático vs dinámico es en realidad ceremonia vs esencia

Según la convención JavaBeans, cada propiedad requiere de un par de métodos (get/set)

El método main() siempre require de String[] como parámetro

Imprimir a consola es muy común, acaso existe alguna manera mas corta?

Page 12: Introduccion A Groovy

12© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 2: Resultado

class HelloWorld { String name

String greet() { return "Hello "+ name }

static void main( args ){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}

Page 13: Introduccion A Groovy

13© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 3: Tipos dinámicos

La palabra reservada def se usa cuando no es necesario indicar el tipo específico de una variable, método o campo (es como var en JavaScript)

Groovy averiguará el tipo correcto en tiempo de ejecución, esto habilita entre otras cosas lo que se conoce como duck typing

Page 14: Introduccion A Groovy

14© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 3: Resultado

class HelloWorld { String name

def greet() { return "Hello "+ name }

static def main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}

Page 15: Introduccion A Groovy

15© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 4: Usar interpolación de variables

Groovy permite la interpolación de variables a través de GStrings (similar a como lo hace Perl)

Basta con rodear una expresión con ${} en cualquier String

Page 16: Introduccion A Groovy

16© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 4: Resultado

class HelloWorld { String name

def greet(){ return "Hello ${name}" }

static def main( args ){ def helloWorld = new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}

Page 17: Introduccion A Groovy

17© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 5: Adios a otras palabras reservadas

La palabra return es opcional en muchos de los casos, el valor de retorno será el valor de la última expresión evaluada en el contexto

La palabra def no es necesaria cuando se trata de métodos estáticos

Page 18: Introduccion A Groovy

18© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 5: Resultado

class HelloWorld { String name

def greet(){ "Hello ${name}" }

static main( args ){ def he new HelloWorld() helloWorld.setName("Groovy") println( helloWorld.greet() ) }}

// OJO versiones anteriores del plugin de Groovy para Eclipse

// requieren que exista el método main definido de la siguiente

// manera//// static void main( String[] args )

Page 19: Introduccion A Groovy

19© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 6: POJOs con esteroides

Los POJOs (o POGOs en Groovy) tienen un constructor por omisión que acepta un Map, dando la impresión de usar parámetros con nombres

Los POGOs suportan la notación de arreglo (bean[prop]) o la notación de objeto (bean.prop) para acceder a sus propiedades (lectura/escritura)

Page 20: Introduccion A Groovy

20© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 6: Resultado

class HelloWorld { String name

def greet(){ "Hello ${name}" }

static main( args ){ def helloWorld = new HelloWorld(name:"Groovy") helloWorld.name = "Groovy" helloWorld["name"] = "Groovy" println( helloWorld.greet() ) }}

Page 21: Introduccion A Groovy

21© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 7: Groovy soporta scripts

A pesar de que Groovy compila a código byte, soporta programas tipo script, los cuales también se compilan a código byte

Todo Script permite definir clases en cualquier parte

Todo script soporta definición de paquetes (package) puesto que al fin y al cabo también son clases Java

Page 22: Introduccion A Groovy

22© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Paso 7: Resultado

class HelloWorld { String name def greet() { "Hello $name" }}

def helloWorld = new HelloWorld(name:"Groovy")println helloWorld.greet()

Page 23: Introduccion A Groovy

23© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Venimos desde aquí...

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() ) }}

Page 24: Introduccion A Groovy

24© 2008 Andres Almiray; disponible bajo CC-SA 2.5

... hasta acá

class HelloWorld { String name def greet() { "Hello $name" }}

def helloWorld = new HelloWorld(name:"Groovy")println helloWorld.greet()

Page 25: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Características I (cerca de casa)

Page 26: Introduccion A Groovy

26© 2008 Andres Almiray; disponible bajo CC-SA 2.5

El lema es ...

Java es Groovy, Groovy es Java

Groovy ofrece una curva de aprendizaje sencilla para desarrolladores Java. Puedes empezar con sintaxis Java y moverte poco a poc a la sintaxis Groovy

98% de código Java es código Groovy, virtualmente podrías renombar un archivo *.java a .groovy y compilaría

Page 27: Introduccion A Groovy

27© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Problemas comunes

La sintaxis de Groovy no es un super-conjunto exacto de la sintaxis de Java dado que no soporta

Inicializadores literales de arreglos int[] arreglo = { 1,2,3 }

definición de clases internas instanciar clases internas no estáticas

A.B ab = instanciaA.new B()

Page 28: Introduccion A Groovy

28© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Características I - JDK5

Groovy soporta anotaciones (JSR 175) iguales a las de Java, es mas, es el segundo lenguage en la JVM que las soporta.

hasta el momento no es definir anotaciones con Groovy

Groovy soporta Enums también Por último también tiene habilitado el soporte de

tipos genéricos, iguales a los de Java.

Page 29: Introduccion A Groovy

29© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Características I - JDK5

Es posible hacer uso de número de argumentos variables (varargs) mediante dos formas

notación triple punto (JDK5) último argumento es de tipo Object[]

Page 30: Introduccion A Groovy

30© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Varargs en acción

class 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

Page 31: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Características II (explorando el vecindario)

Page 32: Introduccion A Groovy

32© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Miscelaneos Parámetros con valor por omisión (PHP) Parámetros con nombre (Ruby), en realidad no

hay tales, pero se puede reusar el truco del constructor por omisión de los POGOs)

Sobrecarga de operadores através de convención de nombres+ plus()

[] getAt() / putAt()

<< leftShift()

Page 33: Introduccion A Groovy

33© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Closures

Closures pueden ser interpretadas como bloques de código reusable, probablemente las hayas visto en otros lenguages como JavaScript o Ruby

Closures substituyen a las clases internas en la mayoría de los casos

Groovy permite “forzar el tipo” de una Closure a una interface de 1 solo método (proxy)

Una closure tendrá un parámetro por omisión llamado it si es que no se defined parámetros para la misma

Page 34: Introduccion A Groovy

34© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Ejemplos de Closures

def 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

Page 35: Introduccion A Groovy

35© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Currying

Currying es una técnica de programación que transforma una función (o closure) de número de parámetros m a otra función con número de parámetros n, donde m > n, es decir reduce el número de parámetros, el valor de cada parámetro reducido queda fijado y no puede cambiarse

Page 36: Introduccion A Groovy

36© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Currying en acción

// un closure con 3 parámetros, el tercero es opcional dado// que define un valor por omisióndef 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

Page 37: Introduccion A Groovy

37© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Iteradores por doquier

Asi como en Ruby, puedes hacer uso de iteradores prácticamente en cualquier contexto

Los iteradores dependen del poder que otrogan las closures, básicamente todos soportan el uso de closures como parámetros

Los iteradores literalmente dejan obsoletos a las operaciones de ciclos

Page 38: Introduccion A Groovy

38© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Iteradores en acción

def 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

Page 39: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Características III (al infinito y mas allá!)

Page 40: Introduccion A Groovy

40© 2008 Andres Almiray; disponible bajo CC-SA 2.5

La palabra reservada as

Permite “Groovy casting”, es decir, convertir un valor de tipoA a tipoBdef intarray = [1,2,3] as int[ ]

Permite forzar (coerce) un closure a una implemnetación anónima de una interface de un solo método

Permite forzar (coerce) un Map a una implementación de interface, clase abstracta o concreta

Permite crear alias en sentencias de importación

Page 41: Introduccion A Groovy

41© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Algunos ejemplos de as

import 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

// Nota esta técnica es similar a crear objetos en JavaScript

// con la notación JSON

Page 42: Introduccion A Groovy

42© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Nuevos operadores

?: (elvis) - un refinamiento del operador ternario

?. referencia segura – permite navegar un grafo de objetos sin temor a NPE

<=> (spaceship) – compara dos valores

* (spread) – expande el contenido de una lista

*. (spread-dot) – aplica el método a todos los elementos de una lista

Page 43: Introduccion A Groovy

43© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Navegando grafos de objetos

GPath es a objetos lo que XPath es a XML

*. y ?. son bastante útiles en esta situación

Escribir expresiones Gpath es muy sencillo dado que los POGOs aceptan notación de punto y arreglo

Page 44: Introduccion A Groovy

44© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Ejemplos de GPath

class 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'

Page 45: Introduccion A Groovy

45© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Metaprogramación

Puedes agregar métodos y propiedades a un objeto en tiempo de ejecución

Puedes interceptar llamadas a métodos o acceso de propiedades (similar a AOP pero sin tanto problema)

Esto significa que Groovy ofrece un concepto similar a las clases abiertas en Ruby, es mas Groovy extiende clases finales como String e Integer

Page 46: Introduccion A Groovy

46© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Ejemplo con categorías

class Pouncer { static pounce( Integer self ){ def s = “Boing!" 1.upto(self-1) { s += " boing!" } s + "!" }}

use( Pouncer ){ assert 3.pounce() == “Boing! boing! boing!"}

Page 47: Introduccion A Groovy

47© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Ejemplo con Metaclases

Integer.metaClass.pounce << { -> def s = “Boing!" delegate.upto(delegate-1) { s += " boing!" } s + "!“}

assert 3.pounce() == “Boing! boing! boing!"

Page 48: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Groovy y Spring

Page 49: Introduccion A Groovy

49© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Varias Alternativas

Compilar el código Groovy a código byte Usar el módulo lang para referencia un

archivo/script groovy Insertar un script en la definición del contexto de

aplicación (XML)

Page 50: Introduccion A Groovy

50© 2008 Andres Almiray; disponible bajo CC-SA 2.5

1. Compilar Groovy

El compilador de Groovy puede ser invocado de distintas maneras

comando groovyc mediante una tarea de Ant (Groovyc) mediante Gmaven, plugin para Maven2 Usando Gant (Groovy + Ant) plugins para IDEs (Eclipse, IDEA, NetBeans)

Page 51: Introduccion A Groovy

51© 2008 Andres Almiray; disponible bajo CC-SA 2.5

2. El módulo lang

Requiere el uso del schema spring-lang Se recomienda usar ApplicationContext, también

se puede usar BeanFactory pero hay mas trabajo manual que realizar

La Inyección de Dependencias funciona de la misma manera

Page 52: Introduccion A Groovy

52© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Referencia a clase Groovy

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xmlns:lang="http://www.springframework.org/schema/lang"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-2.5.xsd">

<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">

<lang:property name="message" value="Hola Mundo!" />

</lang:groovy>

<bean id="bookingService" class="x.y.DefaultBookingService">

<property name="messenger" ref="messenger" />

</bean>

</beans>

Page 53: Introduccion A Groovy

53© 2008 Andres Almiray; disponible bajo CC-SA 2.5

3. Scripts en línea

Requiere las mismas características que la opción anterior

Útil para crear implementaciones de clases ayundates como validadores

Page 54: Introduccion A Groovy

54© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Ejemplo

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xmlns:lang="http://www.springframework.org/schema/lang"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-2.5.xsd">

<lang:groovy id="messenger">

<lang:inline-script>

class GroovyMessenger implements Messenger { String message }

</lang:inline-script>

<lang:property name="message" value="Hola Mundo!" />

</lang:groovy>

</beans>

Page 55: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Preguntas y Respuestas

Page 56: Introduccion A Groovy

56© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Información adicional

Groovy, guías, ejemploshttp://groovy.codehaus.org

Groovy Eclipse Pluginhttp://groovy.codehaus.org/Eclipse+Plugin

Noticias Groovyhttp://aboutgroovy.comhttp://groovyblogs.orghttp://groovy.dzone.comhttp://groovy.org.es

Mi blog sobre Groovy/Java/Swinghttp://jroller.com/aalmiray

Page 57: Introduccion A Groovy

© 2008 Andres Almiray; disponible bajo CC-SA 2.5

Gracias!