Fullmenu null

 

20 August 2017

Groovy es muy parecido a Java, de hecho puedes usar código Java y prácticamente será válido en Groovy. Al igual que en Java, puedes declarar clases, definir herencia, interfaces, etc pero además Groovy aporta algunas funcionalidades y clases muy útiles que le hacen menos "verbose" que Java.

Una de estas funcionalidades es el poder crear ficheros Scripts que pueden ser ejecutados directamente por Groovy sin necesidad de pasar por todo el proceso de compilación lo cual le hace muy útil por ejemplo para crear utilidades orientadas a los administradores de sistemas.

En este post vamos a crear un script básico donde poder ver alguna de las características que le hacen especial.

Punto y coma, paréntesis y demás

Sí, el famoso asunto del punto y coma es lo primero que se comenta cuando empiezas con Groovy. Efectivamente Groovy no necesita que termines las sentencias en ";" pues es capaz de deducirlo por la sintaxis y el contexto. De todas formas si quieres ponerlo tampoco le molesta.

Cuando usamos una única función en una línea tampoco es necesario el uso de paréntesis con lo que ganamos en legibilidad

println("no necesito un punto y coma al final")

println "Yo tampoco, ni los parentesis"

Declaración de tipos

La siguiente batalla que afrontarás será la declaración de tipos o no (tipado estático vs tipado dinámico).

Groovy admite ambos tipos de declaración por lo que puedes declarar tus variables y funciones indicando el tipo de dato, pero disponer de una declaración dinámica de tipos puede hacer tu código mucho más versatil y legible.

Cuando no nos importe el tipo de dato de una variable (o retorno de una función) usaremos def de tal forma que Groovy buscará en tiempo de ejecución si ese objeto implementa los métodos que indiquemos

String myString

def unObjeto

unObjeto = "soy un string"

println unObjeto

unObjeto = 10

println unObjeto

Comillas simples y dobles

Podemos declarar cadenas usando tanto la comilla simple como la comilla doble, de tal forma que podemos incluir una de ellas en la otra.

Además si queremos usar un String multilinea podemos hacerlo mediante el uso de tres comillas dobles evitando el uso de caracteres de escape

println "Necesito una comilla simple ' "
println 'Necesito una comilla doble " '
println """Necesito muchas lineas
donde poder ver los retornos de carro
sin tanto lio como concatenando String """

String vs GString

Groovy añade la clase GString que es muy similar a String. De hecho en los ejemplos anteriores cuando usabamos la cadena doble en realidad estabamos instanciando un GString.

La utilidad que tiene esta clase es que nos permite insertar código en la cadena que será evaluado en el momento de utilizar la variable evitando las tipicas concatenaciones de cadenas de java:

println "Mira lo que puedo hacer ${2+2} simplemente con el dolar y las llaves"

Closure

Mucho antes de que Java implementará las famosas Lambdas, Groovy proporciona el concepto de closure

Una closure es un pedazo de código anónimo, en el sentido de que no se declara como una función sino que se asigna a una variable. Por lo demás puede recibir parámetros y devolver un resultado como cualquier función. Podemos invocarla mediante el método implícito call(argumentos) o incluso pasarla como parámetro

def unaClosure = { param ->
    "${param}".reverse()
}

println unaClosure.call("una cadena")
println unaClosure.call(10)

Listas, mapas y otros seres

Declarar listas y mapas, asi como asignarlos es trivial

def lista = [1, 3, 4, "Una cadena", new Date() ]
List otraLista = [1, 3, 4, "Una cadena", new Date() ]

def mapa = [ clave : "valor", otra_clave: "otro valor"]

Bucles

Además del típico for(int i=0; i<10;i++){ } y sus derivados, Groovy proporciona alguna forma más de realizar bucles siendo "each", para recorrer todos los elementos de una lista/map, uno de los más usados

lista.each{ println "it es un objeto de la lista $it"}
mapa.each{ println "it es un Map.Entry $it.key=$it.value" }

Si necesitamos conocer en cada iteración además del elemento, la posición que ocupa en la lista usaremos "eachWithIndex"

lista.eachWithIndex{ ele, idx ->    //(1)
    println "posicion $idx, elmenento $ele"
}
  1. La closure recibe dos parámetros


Script
println("no necesito un punto y coma al final")

println "Yo tampoco, ni los parentesis"

String myString

def unObjeto

unObjeto = "soy un string"

println unObjeto

unObjeto = 10

println unObjeto

println "Necesito una comilla simple ' "
println 'Necesito una comilla doble " '
println """Necesito muchas lineas
donde poder ver los retornos de carro
sin tanto lio como concatenando String """

println "Mira lo que puedo hacer ${2+2} simplemente con el dolar y las llaves"

def unaClosure = { param ->
    "${param}".reverse()
}

println unaClosure.call("una cadena")
println unaClosure.call(10)

def lista = [1, 3, 4, "Una cadena", new Date() ]
List otraLista = [1, 3, 4, "Una cadena", new Date() ]

def mapa = [ clave : "valor", otra_clave: "otro valor"]

lista.each{ println "it es un objeto de la lista $it"}
mapa.each{ println "it es un Map.Entry $it.key=$it.value" }

lista.eachWithIndex{ ele, idx ->    //(1)
    println "posicion $idx, elmenento $ele"
}