Charla de Codemotion Madrid 2014
Vídeo disponible en: https://www.youtube.com/watch?v=GqfYw0lcANw
Groovy es un lenguaje magnífico, muy divertido de programar, que hace que trabajar con la JVM sea un placer. A menudo se habla de que tiene una curva de aprendizaje casi nula desde Java. El problema es que esto lleva a que se desconozca gran parte de su potencial.
En esta charla quiero comentar a modo de "pildoras" algunos de los aspectos más interesantes de groovy. Para ello me basaré en mi propia experiencia, y en el magnífico libro "Groovy Goodness Notebook".
11. Groovy
¿Qué sabe mucha gente sobre
Groovy?
● Los archivos llevan extensión .groovy
● No lleva punto y coma al final
● Es casi al 100% compatible con código java
17. Groovy
Disclaimer
● No quiero trollear a Java
● Java 8 ha dado un paso de gigante
● Pero Groovy mola más ;)
● Espero que todo el mundo aprenda algo
20. Básicos y misceláneos de groovy
public class Saludador {
private String usuario;
public String getUsuario() {
return usuario;
}
public void setUsuario(usuario) {
this.usuario = usuario;
}
public String saluda(String nombre){
return ("Hola " + nombre + ", yo soy " + usuario);
}
}
Saludador saludador = new Saludador();
saludador.setUsuario("Pablo");
System.out.println(saludador.saluda("Guillaume"));
Puntos y coma
opcionales
21. Básicos y misceláneos de groovy
public class Saludador {
private String usuario
public String getUsuario() {
return usuario
}
public void setUsuario(usuario) {
this.usuario = usuario
}
public String saluda(String nombre){
return ("Hola " + nombre + ", yo soy " + usuario)
}
}
Saludador saludador = new Saludador()
saludador.setUsuario("Pablo")
System.out.println(saludador.saluda("Guillaume"))
Paréntesis
opcionales
22. Básicos y misceláneos de groovy
public class Saludador {
private String usuario
public String getUsuario() {
return usuario
}
public void setUsuario(usuario) {
this.usuario = usuario
Returns
opcionales
}
public String saluda(String nombre){
return "Hola " + nombre + ", yo soy " + usuario
}
}
Saludador saludador = new Saludador()
saludador.setUsuario "Pablo"
System.out.println saludador.saluda("Guillaume")
23. Básicos y misceláneos de groovy
public class Saludador {
private String usuario
public String getUsuario() {
Public
opcionales
usuario
}
public void setUsuario(usuario) {
this.usuario = usuario
}
public String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
}
Saludador saludador = new Saludador()
saludador.setUsuario "Pablo"
System.out.println saludador.saluda("Guillaume")
24. Básicos y misceláneos de groovy
class Saludador {
private String usuario
String getUsuario() {
usuario
}
void setUsuario(usuario) {
this.usuario = usuario
}
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
Tipos
opcionales
}
Saludador saludador = new Saludador()
saludador.setUsuario "Pablo"
System.out.println saludador.saluda("Guillaume")
25. Básicos y misceláneos de groovy
class Saludador {
private String usuario
String getUsuario() {
usuario
}
void setUsuario(usuario) {
this.usuario = usuario
}
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
}
def saludador = new Atajo Saludador()
para print
saludador.setUsuario "Pablo"
System.out.println saludador.saluda("Guillaume")
26. Básicos y misceláneos de groovy
Getters y
setters
opcionales
class Saludador {
private String usuario
String getUsuario() {
usuario
}
void setUsuario(usuario) {
this.usuario = usuario
}
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
}
def saludador = new Saludador()
saludador.setUsuario "Pablo"
println saludador.saluda("Guillaume")
27. Básicos y misceláneos de groovy
class Saludador {
private String usuario
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
Invocación al
setter "mágica"
}
def saludador = new Saludador()
saludador.setUsuario "Pablo"
println saludador.saluda("Guillaume")
28. Básicos y misceláneos de groovy
class Saludador {
private String usuario
Constructor por
parámetros con
nombre "mágico"
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
}
def saludador = new Saludador()
saludador.usuario = "Pablo"
println saludador.saluda("Guillaume")
29. Básicos y misceláneos de groovy
class Saludador {
private String usuario
Cadenas
interpoladas
(GStrings)
String saluda(String nombre){
"Hola " + nombre + ", yo soy " + usuario
}
}
def saludador = new Saludador(usuario:"Pablo")
println saludador.saluda("Guillaume")
30. Básicos y misceláneos de groovy
class Saludador {
private String usuario
String saluda(String nombre){
"Hola $nombre, yo soy $usuario"
}
}
def saludador = new Saludador(usuario:"Pablo")
println saludador.saluda("Guillaume")
Reformateamos...
31. Básicos y misceláneos de groovy
class Saludador {
private String usuario
String saluda(String nombre){
"Hola $nombre, yo soy $usuario"
}
}
def saludador = new Saludador(usuario:"Pablo")
println saludador.saluda("Guillaume")
public class Saludador {
private String usuario;
public String getUsuario() {
return usuario;
}
public void setUsuario(usuario) {
this.usuario = usuario;
}
public String saluda(String nombre){
return ("Hola " + nombre + ", yo soy }
}
Saludador saludador = new Saludador();
saludador.setUsuario("Pablo");
System.out.println(saludador.saluda("Guillaume"));
33. Básicos y misceláneos de groovy
Dinámico
def saluda() {
def a = "hola mundo"
println a
a = 3
print a
}
void despidete() {
Integer a = 3
println a
a = "adios" // Error en tiempo de ejecución
println a
}
34. Básicos y misceláneos de groovy
Estático. Si quieres.
import groovy.transform.CompileStatic
@CompileStatic
void despidete() {
Integer a = 3
println a
a = "adios" //Error en tiempo de compilación
println a
}
35. Básicos y misceláneos de groovy
Comparación de cadenas
def a = "hola"
assert "hola" == a
36. Básicos y misceláneos de groovy
Return opcional
String suma(int a, int b) {
a + b
}
assert suma(2, 3) == 5
37. Básicos y misceláneos de groovy
Casting automático
String diTuNombre() {
Integer a = 3
}
def a = diTuNombre()
assert a == "3"
assert a.class == String
38. Básicos y misceláneos de groovy
Casting automático
class User{
String nombre
Integer edad
}
def user1 = new User(nombre:"Pablo", edad:36)
assert user1.class == User
def user2 = [nombre:"Pablo", edad:36] as User
assert user2.class == User
User user3 = [nombre:"Pablo", edad:36]
assert user3.class == User
39. Básicos y misceláneos de groovy
Método with
class User{
String nombre
Integer edad
}
def user = new User()
user.with {
nombre = "Pablo"
edad = 36
}
def sb = new StringBuilder()
sb.with {
append 'Just another way to add '
append 'strings to the StringBuilder ’
append 'object.'
}
41. Básicos y misceláneos de groovy
Listas (arrays)
//JAVA
String[] lista = new String[] { "uno", "dos", "tres" };
//GROOVY
def lista = ['uno', 'dos', 'tres']
// Las listas tienen length, igual que los arrays
assert 3 == lista.length
// Además tienen size
assert 3 == lista.size()
42. Básicos y misceláneos de groovy
Mapas
//JAVA
Map <String, String> mapa = new HashMap<String, String>();
mapa.put("nombre", "Pablo");
mapa.put("apellido", "Alba");
//GROOVY
def mapa = [nombre:"Pablo", apellido:"Alba"]
43. Básicos y misceláneos de groovy
La verdad en Groovy
assert !( null )
assert !( "" )
assert !( [] )
assert !( [:] )
assert !( 0 )
assert new Object()
assert "string"
assert [1, 2, 3]
assert [a:1]
assert 12345
44. Básicos y misceláneos de groovy
Groovy como lenguaje de scripting
Hola.java
class Hola {
public static void main(String[] args){
System.out.println ("Hola " + args[0]);
}
}
javac Hola.java
java Hola Pablo
45. Básicos y misceláneos de groovy
Groovy como lenguaje de scripting
meDaIgualElNombre.groovy
println "Hola " + args[0]
groovy meDaIgualElNombre.groovy
46. Básicos y misceláneos de groovy
Hook de cerrado
addShutdownHook {
println 'Fin del script'
}
println 'Inicio del script'
Thread.sleep 100000
48. Operadores
Navegación segura
// Modo "JAVA"
if (company != null && company.getAddress() != null
&& company.getAddress().getStreet() != null) {
println company.address.street.name
}
// Modo "Groovy"
println company?.address?.street?.name
49. Operadores
Operador Elvis
def sampleText
// Operador ternario normal
def ternaryOutput = (sampleText != null) ? sampleText : 'Hello Groovy!'
// Operador Elvis
// Esto se lee: 'Si sampleText no es nulo, asigna sampleText a
// elvisOutput. De otra forma, asigna 'Viva Las Vegas!' a elvisOutput.
def elvisOutput = sampleText ?: 'Viva Las Vegas!'
50. Operadores
In
// Modo "JAVA"
String[] list = {"a", "b", "c"};
assert Arrays.asList(list).contains("a")
// Modo "GROOVY"
def list = ["a", "b", "c"]
assert "a" in list
53. Strings
Comillas simples
def s1 = 'Esto es una cadena, y podemos usar "comillas dobles"
sin escaparlas’
54. Strings
Comillas simples triples
def s1 = ‘‘‘Esto es una cadena multilínea
podemos escribir
un montón de líneas
sin preocuparnos de todo
el lío de la concatenación
’’’
55. Strings
Slashy
def s3 = /Podemos meter casi cualquier cosa en una "string" 'slasy' sin
escaparla. Se usa mucho para expresiones regulares/
56. Strings
Comillas dobles
def s1 = "Esto es una cadena, y podemos usar ‘comillas simples’
sin escaparlas"
57. Strings
Comillas dobles triples
def s1 = """Esto es una cadena multilínea
podemos escribir
un montón de líneas
sin preocuparnos de todo
el lío de la concatenación
"""
58. Strings
GStrings
def nombre = "Pablo"
def s1 = "Hola, $nombre"
assert s1 == "Hola, Pablo"
def edad = 36
def s2 = "Naciste en el año ${2014 - edad}"
assert s2 == "Naciste en el año 1978"
59. Strings
Invocación de métodos dinámica
Adiós, Reflection!
class Simple {
def hola(nombre) {
"Hola $nombre, ¿cómo estás?"
}
}
def s = new Simple()
def method = 'hola'
assert 'Hola Pablo, ¿cómo estás?' == s."$method"('Pablo')
60. Strings
¿Es un número?
'42.42'.isNumber()
'42.42'.isDoble()
'42.42'.isFloat()
'42.42'.isInteger()
'42.42'.isLong()
61. Strings
Substrings
def s = 'Acceder a las cadenas en Groovy es fácil.'
assert 'A' == s.getAt(0)
// Las cadenas funcionan como listas
assert 'A' == s[0]
assert 'Groovy' == s[25..30] // Podemos usar rangos.
63. Strings
Base64
def s = 'Esto en otros lenguajes es un dolor...'
String encoded = s.bytes.encodeBase64().toString()
assert 'RXN0byBlbiBvdHJvcyBsZW5ndWFqZXMgZXMgdW4gZG9sb3IuLi4=' == encoded
byte[] decoded = encoded.decodeBase64()
assert s == new String(decoded)