Secciones

Artículos para tus primeros pasos

Si estás empezando a introducirte en el mundo de Groovy y Grails, no te pierdas nuestros artículos básicos: 

Entrevistas con los expertos
 

Los protagonistas te cuentan de qué van los proyectos más importantes del mundo Groovy:


Un proyecto de:
ImaginaWorks
Campus Escuela de Groovy

Introducción a Groovy, parte 2

lunes 27/08/2007

1. Introducción

En el artículo previo, Introducción a Groovy, vimos lo primeros pasos para hacer programas en Groovy, algunas de las ventajas sobre la sintaxis que éste ofrece y un vistazo rápido a algunos de los tipos de datos que soporta. En esta edición veremos otras características que hacen de Groovy un lenguaje excepcional y una opción muy interesante para aplicarlo como lenguaje de programación cotidiano.

2. La Verdad en Groovy

Si alguna vez programaste en lenguaje C, recordarás que una condición podía ser evaluada de manera numérica, donde cero era igual a falso y cualquier otro número era igual a verdadero. Java define las condiciones para que se evalúen en contexto booleano, es decir, si el valor no es equiparable a un primitivo boolean el compilador generará un error. En Groovy, la verdad tiene otros matices y se extiende mas allá que la evaluación booleana, la siguiente tabla describe las reglas y el orden en que se aplican para determinar si una condición es verdadera:


TipoCriterio de evaluación
Booleanel valor es igual a true
Matcherexiste al menos una coincidencia en el patrón
Collectionla colección no es vacía
Mapel mapa no es vacío
String, GStringla cadena no es vacía
Number, Characterel valor es distinto de cero (como en Lenguaje C)
otro tipola referencia no es nula

Cabe destacar que el tipo se determina en tiempo de ejecución.

3. Expresiones Regulares

Como muchos otros lenguajes tipo script y/o dinámicos, Groovy soporta el uso de expresiones regulares de manera "nativa", es decir que puedes declarar y usar dichas expresiones sin necesidad de construcciones "aparatosas" o sintaxis adicional al las construcciones básicas del lenguaje, como es el caso de Java. En Groovy basta con declarar la expresión de búsqueda entre barras diagonales, como en Perl, y usar uno de los tres operadores disponibles:

=~ búsqueda de ocurrencias (produce un java.util.regex.Matcher)
==~ coincidencias (produce un Boolean)
~ patrón

 

Listado 3.1
 

def texto = "Groovy es un lenguaje dinámico"
assert texto =~ /ua/   // según la verdad en Groovy
                       // &eecute;sta expresión es verdadera
matcher = texto =~ /ua/
assert matcher instanceof java.util.regex.Matcher

def coincidencia = texto ==~ /.*ua.*/
assert coincidencia instanceof java.lang.Boolean
assert coincidencia

def patrón = ~/oovy/
def resultado = patrón.matcher(texto)
assert resultado instanceof java.util.regex.Matcher

El primer ejemplo define una expresión regular y busca si existe alguna ocurrencia de la misma en la cadena de caracteres 'texto', dado que lenguaje posee el diptongo 'ua' la búsqueda tiene éxito. El segundo ejemplo aplica la expresión regular a todo el contenido de la cadena 'texto', si ésta se cumple entonces el resultado es un Boolean con valor verdadero. El tercer ejemplo compila una expresión regular en un patrón, lo cual permite un mejor rendimiento en ejecución. Como podrás notar la variable patrón tiene un acento, este no es un error, puedes copiar el código anterior y ejecutarlo en grooysh o groovyConsole y funcionará sin problemas, esto se debe que al igual que Java, Groovy soporta caracteres Unicode.


4. Redefiniendo operadores

Desde que Java se hizo público un número considerable de desarrolladores suplicaban por la capacidad de sobreescribir operadores en el lenguaje, de manera similar como C++ u otros lenguajes que lo permiten. La buena noticia es que Groovy si lo permite, a través de una convención de nombres en los métodos involucrados. La siguiente tabla resume los operadores típicos pero hay muchos mas (la lista completa podrás encontrarla en el capítulo 3 de "Groovy in Action", también en ésta liga)

OperaciónMétodo
a + ba.plus(b)
a - ba.minus(b)
a * ba.multiply(b)
a / ba.div(b)
Con solo incluir algunos de los métodos de la lista en una clase que codifiques, automáticamente podrás usar el operador correspondiente, lo cual permite lo siguiente:

Listado 4.1


texto = "Programación" - "ción" + "dor"
assert "Programador" == texto

lista = [1,2,3]
lista += [4,5,6]
assert [1,2,3,4,5,6] == lista
lista << 7  // lista.leftShift(7) -> lista.add(7)
assert [1,2,3,4,5,6,7] == lista

s = "A" * 5
assert s == "AAAAA"
s = "ABCDE"
assert "BC" == s[1..2]  // s.getAt([1..2]); operación con rango
assert "C" == s[2]  // s.getAt(2) -> s.charAt(2)

Dado esto y otras características de Groovy, es muy sencillo crear Lenguajes de Dominio Específico (o DSL por sus siglas en Inglés) los cuales proveen otro tipo de ventajas, las cuales veremos en un artículo posterior.


5. De POJOs a POGOs

Sin lugar a dudas en los últimos años se ha visto un resurgimiento de los comúnmente llamados POJOs (Plain Old Java Objects) que en realidad son un subconjunto de la convención JavaBeans propuesta por Sun. Así es, son un subconjunto puesto que los JavaBeans deben notificar cualquier cambio que se realice en alguna de sus propiedades, y los POJOs como comúnmente se codifican no lo hacen. Basta con dar una mirada a proyectos como Spring y Hibernate y veremos las ventajas de su uso, sin embargo es muy molesto escribir métodos de acceso para cada propiedad, algunos Ambientes de Desarrollo Integrados (IDE) proveen herramientas para generar este tipo de código, pero Groovy va mas allá, simplemente con declarar las propiedades según la convención los métodos de acceso serán generados, a este tipo de componentes les llamamos entonces POGOs (como los POJOs, pero en vez de Java, Groovy). Las propiedades en un POGO se declaran con tipo y nombre, sin modificador de acceso, ya que de tenerlo entonces no son una propiedad sino mas bien un campo (field). Veamos esto mas a detalle:

Listado 5.1


class Persona {
   String nombre
   String apellido
   private int id

   String toString() { "${nombre} ${apellido}" }
}

Persona persona = new Persona( nombre: 'Andres', apellido: 'Almiray' )
assert "Andres Almiray" == persona.toString()
persona.apellido = "Jaramillo"
assert "Andres Jaramillo" == persona.toString()
persona['apellido'] = "Almiray"
assert "Andres Almiray" == persona.toString()

Paso por paso: Primero definimos un POGO llamado Persona, el cual consta de 2 propiedades [nombre,apellido] y un campo [id]; sabemos que es así por que los primeros no tienen modificador de acceso y el último sí. Luego creamos una instancia del POGO y vemos algo curioso, el constructor parece soportar parámetros con nombres, en realidad lo que esta escrito es un Mapa extendido (no hay corchetes), esto se debe a que Groovy anexa un constructor por omisión a los POGOs; El cual recibe un Mapa como parámetro - genial! - no te parece? En el tercer paso imprimimos el valor literal del POGO, el cual usa un GString en el método toString(), cambiamos el valor de la propiedad 'apellido' y verificamos de nuevo. Nota que el acceso de propiedad también se puede hacer con corchetes. El acceso a campos también puede realizarse mediante el operador '.' o '[]' lo cual daría la impresión de que se ha roto la encapsulación del POGO. Es posible obtener y modificar el valor de un campo mediante el operador '.@'. Veamos que sucede cuando insertamos propiedades sintéticas.

Listado 5.2

class Persona {
   String nombre
   String apellido
   private int id

   String toString() { "${nombre} ${apellido}" }
   def getNombreCompleto() { "${nombre} ${apellido}" }
}

Persona persona = new Persona( nombre: 'Andres', apellido: 'Almiray' )
assert persona.nombre  == "Andres"
assert persona.@nombre  == "Andres"
assert persona.nombreCompleto == "Andres Almiray"
try{ assert persona.@nombreCompleto == "Andres Almiray" }
catch( MissingFieldException e ){
   println "ERROR, nombreCompleto no es un campo de Persona"
}

// imprime
// "ERROR, nombreCompleto no es un campo de Persona"

Recordando que un POJO/POGO no es un JavaBean (mas bien un subconjunto), existe la propuesta en la siguiente versión del lenguaje, para que se incluya un mecanismo que permita marcar cuales propiedades deben permitir la publicación de eventos, cuando su valor cambie, el modelo actual es a través de anotaciones como en el siguiente ejemplo:

Listado 5.3

class Persona {
   @BoundProperty String nombre
   @BoundProperty String apellido
}

Este último ejemplo pone en evidencia otra característica única de Groovy hasta el momento, es el segundo lenguaje en la plataforma Java que soporta anotaciones (el primero es Java por supuesto), el soporte para tipos genéricos (introducidos en Java5) también viene en camino.


6. Conclusión

En esta ocasión hemos visto ejemplos de otras características del lenguaje Groovy, que hacen el trabajo cotidiano mas agradable y sencillo. Como probablemente ya te habrás dado cuenta, Groovy posee características de otros lenguajes y al mismo tiempo ofrece una integración excelente (mas no limitativa) con la plataforma y el lenguaje Java. Espero que esta muestra del lenguaje te halla incentivado a continuar aprendiendo Groovy.
Nota: Todos los ejemplos en este artículo y el anterior pueden ser ejecutados con groovy (el intérprete), groovysh y groovyConsole.

Andrés es un Programador Java certificado, Desarrollador de Aplicaciones Web certificado, con más de 7 años de experiencia en diseño y desarrollo de aplicaciones. El ha estado involucrado en muchos desarrollos de aplicaciones web y desktop seleccionando el conjunto de herramientas y tecnologías mas apropiadas. También ha sido profesor de cursos de ciencias de la computación en el instituto educativo más prestigioso de México. Sus interese actuales incluyen arquitectura de software, Developer Testing, Groovy, Spring, AOP y Swing.


Más información: http://groovy.org.es

Contenidos relacionados:



3 comentarios:

Introducción a Groovy, parte 2

fibonacci - miércoles 29/08/2007

Gracias por la serie de artículos Andrés, y enhorabuena. Me está sirviendo para repasar conceptos que no tenía del todo claros.

Re:Introducción a Groovy, parte 2

AndresAlmiray - viernes 31/08/2007

No hay problema =) que bueno que te han servido los artículos. Los siguientes tratarán temas mas avanzados como el MOP =)

Re:Re:Re:Re:Introducción a Groovy

Andres Almiray - viernes 31/08/2007

Hmm, entonces no funcionó adecudamente si existe al menos un espacio en la ruta de instalación? le haré el comentario a Joachim, para ver que puede hacerse con el instalador.

Tienes que estar registrado para iniciar sesión y poder publicar tus comentarios