Post on 25-May-2015
Alberto Vilches http://albertovilches.com
Twitter @albertovilches
Taller de DSLs en Groovy
QUÉ ES UN DSL
DSL = Lenguaje con un propósito
VS
GPS = lenguaje con múltiples propósitos
XML, EL ANTEPASADO DEL DSL EN JAVA
• ejb-jar.xml
– Define la estructura para desplegar EJBs en SA
• struts-config.xml
– Mapea las acciones y forms del fw MVC Struts
• spring-config.xml
– Define cómo crear e inyectar objetos en LC Spring
CARACTERÍSTICAS DE UN DSL
• Sintaxis específica
• Limitados en ámbito y capacidad
• Pequeños y simples
POR QUÉ SON ÚTILES
• Contextuales
• Más expresivos = más claros
• Mejor usar varios DSL que un único GPL
CUANDO USARLOS
• Lógica o reglas de negocio cambian a menudo
• Solución separada del resto del código de la aplicación
TIPOS DE DSL
• Externos
• Los usamos día a día desde hace tiempo
• Internos
• Viven entre nosotros
TIPOS DE DSL: EXTERNOS
Cómo definen su formato y sintaxis:
Aprovechan una sintaxis existente como XML…
…o poseen su propio compilador/interprete…
…o son diseñados con una herramienta
EJEMPLOS DE DSLS EXTERNOS
Cascading Style Sheet
EJEMPLOS DE DSLS EXTERNOS
Script Apache Ant (XML)
EJEMPLOS DE DSLS EXTERNOS
• Structured Query Language
• Expresiones regulares
Patrón para buscar emails
EJEMPLOS DE DSLS EXTERNOS
DSL Dominio Uso
SQL BBDD Consulta y manipulación
Expresión regular
Cadenas de texto Búsqueda por patrones
CSS Estilo (fuentes, colores, tamaños, etc)
Cambiar la presentación de un HTML
Ant Recursos (clases y otros ficheros)
Compilación y generación de artefactos JAR,WAR
TIPOS DE DSL: INTERNOS
• Se hospedan en un GPL para describirlos
• Aprovechan el compilador/intérprete
• Reutilizan parte de la sintaxis
• Heredan las limitaciones del lenguaje anfitrión
DSLS INTERNOS GRAILS Config.groovy / DataSource.groovy
DSLS INTERNOS GRAILS UrlMappings.groovy
DSLS INTERNOS GRAILS Criteria, Hibernate, SQL
DSLS INTERNOS GRAILS GORM
QUÉ DEFINE UN DSL • Contexto
– El dominio está implícito porque…
– … sistema, autor y lector saben de qué se está hablando
• Estructura, gramática, sintaxis es:
– Reducida è fluida è agrupada è encadenada
SINTAXIS FLUIDA
• Primera aproximación
“Method chaining”
Todos los métodos devuelven this
METHOD CHAINING
• Javascript jQuery
METHOD CHAINING
• Javascript jQuery
• Contextual, ligeramente extensible
METHOD CHAINING
• Apache Commons CLI
METHOD CHAINING
No vale siempre
(aunque es mejor que nada)
• No es fácil anidar • Todo en una misma línea
EJEMPLO: SIN CONTEXTO
• ¿Construcción o reutilización de recursos? • ¿Importa el orden? ¿Qué hago si falla?
EJEMPLO: METHOD CHAINING
• Único objeto, única línea, único contexto • ¿Control de errores y recursos?
SOLUCIÓN: DSL
• DSL
API vs DSL
DSLS EXTERNOS
• Jet Brains Metra Programming System http://www.jetbrains.com/mps/index.html
• Eclipse Modeling Framework Project http://www.eclipse.org/modeling/emf/
• Microsoft DSL Tools Visualization&Modeling SDK http://code.msdn.microsoft.com/DSLToolsLab
• XML
• ANTLR http://www.antlr.org/
DSLS INTERNOS
• No todos los lenguajes lo permiten facilmente
• Metraprogramación es esencial
• Ruby • Groovy
GROOVY • Lenguaje dinámico para JVM
– Atributos y métodos se resuelven en Runtime
– Meta Object Protocol (MOP)
– Genera clases 100% Java
• Sintaxis Java
+ sintaxis específica para colecciones
+ otras ideas de Ruby, Python, Smalltalk
• Closures, scripts, sobrecarga operadores, MOP, Gstrings, Categorías, metaClass
SCRIPTS
COLECCIONES
ALGUNAS MEJORAS Getters Setters Constructores
con mapas Paréntesis y corchetes Opcionales No primitivos
EXPANDOMETACLASS
• Se pueden añadir métodos/atributos a cualquier clase
• ¡Incluso reescribir! • y mucho más..
CATEGORIES
• Sobreescritura de métodos temporal
SOBRECARGA DE OPERADORES
CALL() SHORTHAND
• Se puede invocar a cualquier objeto como si fuera un método
• Solo es necesario implementar call()
MOP • Se pueden capturar las llamadas a
métodos que no existen
CLOSURES
Java
Groovy
CLOSURES
• Variables invocables como métodos
• Atributos invocables como métodos
CLOSURES
• Owner: instancia donde se crea el closure
• Delegate: contexto donde se ejecuta el closure
• Por defecto es la misma (delegate = owner)
þ
CLOSURES
• El contexto por defecto es owner • Accediendo a variable de owner
funciona
þ
CLOSURES • El contexto por defecto es owner • Accediendo a variable de otro sitio
NO funciona
þ ý
CLOSURES
• Contexto nuevo (delegate): config • Accediendo a variable del contexto SI
funciona
þ
CLOSURES
• With simplemente cambia el contexto
ESTRUCTURAS PERSONALIZADAS
• En un método dado, si el último parámetro es un closure, se puede dejar fuera del paréntesis que engloba los parámetros de la llamada
MI PRIMER DSL
MI PRIMER DSL
MI PRIMER DSL
MI PRIMER DSL
DSL EN UN SCRIPT src/script.groovy
PERO…
PERO…
PERO…
PERO…
BUILDER SUPPORT
• Los builders procesan DSLs mediante eventos
• La clase BuilderSupport nos permite crear nuestros propios builders
• Admite cualquier nombre de método y combinación de parámetros
BUILDER SUPPORT
MARKUP BUILDER
SWING BUILDER
JMX BUILDER
• Creando un cliente JMX
• Exportando un objeto mediante JMX
ANT BUILDER
GANT
• http://gant.codehaus.org/
GRIFFON
• http://griffon.codehaus.org/
EASYB
• http://www.easyb.org/download.html
GRADLE
• http://gradle.org/
GMETRICS
• http://gmetrics.sourceforge.net/
SPOCK
• http://code.google.com/p/spock/
Taller!