SlideShare ist ein Scribd-Unternehmen logo
1 von 24
Downloaden Sie, um offline zu lesen
GROOVY E DSL
BY TIZIANO LATTISI
INDICE
• cos’è Groovy?
• caratteristiche interessanti (a mio giudizio), in ordine
arbitrariamente sparso
• cos’è un DSL?
• caratteristiche che rendono Groovy adatto a costruire un DSL
• un esempio semplice (lo facciamo al volo)
• un esempio meno semplice (non lo facciamo al volo)
nota: in parallelo vedremo esempi
COS’È GROOVY (PARTE 1)?
• linguaggio per la JVM alternativo a Java
• ispirato a: Ruby, Python, Smalltalk
• consente compilazione dinamica, ma può anche
generare bytecode
• tipizzazione forte dinamica
• closure
COMMAND-LINE GROOVY
HELLO GROOVY
• $ groovy -e “println ‘Hello Groovy’”!
• $ echo “println ‘Hello Groovy’” > hello.groovy

$ groovy hello.groovy!
• $ groovy -Dmsg=Groovy -e “println ‘Hello ‘ +
System.getProperty(‘msg’)”
COMMAND-LINE GROOVY
SWITCH -N -P -I
• $ printf “1n2” > data.txt

$ groovy -n -e “println line.toLong()*2” data.txt

2

4!
• $ groovy -i.bak —n -p -e “line.toLong()*2” data.txt

$ cat data.txt

2

4

$ cat data.txt.bak

1

2

COMMAND-LINE GROOVY
SWITCH -L
• $ groovy -l 1234 -e “if(line==‘DATE’){println new Date()}”

Groovy is listening on port 1234



$ telnet localhost 1234

Connect to localhost.

Escape character is ‘^]’.

DATE

Mon Mar 17 21:38:49 CET 2014!
• $ groovy -l 80 SimpleWebServer.groovy



Esempio nei sorgenti Groovy: serve i file di una cartella
come webserver

COS’È GROOVY (PARTE 2)?
• è possibile usare direttamente l’API Java
• accetta (salvo alcune eccezioni) anche sintassi Java (es. {1,2,3,4} non è
array, ma [1,2,3,4] è un ArrayList)
• import automatico (di convenienza) di alcune classi Java (es. java.io,
java.lang, java.net, java.util…)
• println -> System.out.println
• parentesi opzionali nella chiamata a metodi
• notazione breve per getter e setter (o.field -> o.getField())
• ; opzionale (salvo alcune eccezioni)
• return opzionale (viene restituita l’ultima valutazione)
• this usata in contesti statici punta alla classe
COS’È GROOVY (PARTE 3)?
• GString interpolation: “Hello ${name}”
• Lazily interpolation (eval in conversione a String): “Nr. ${-> i}”
• == -> equals, equals -> is: non più “a != null && a.equals()” !!
• in: è un operatore basato su contains(): 3 in [1,2,3,4]
• sintassi nativa per alcune strutture dati: [1,2,3] list, [TN:’Trento’,
BZ:’Bolzano] map, 1..10 range
• contesti booleani: if( myString!=null && myString.length>0 ){} ->
if(myString){}
• safe-dereferencing: email?.destinatario?.indirizzo
• costrutto and-or (Elvis operator):

def result = name != null ? name : “Unknow”
FOR E FOR EACH
• for (int i=0; i<n; i++) { … }!
• for (i in 0..n-1) { … }!
• for (i in 0..<n) { … }!
• n.times { … }

• (1..5).each { println “nr. $it” }!
• 1..5 instanceof List!
• { println “nr. $it” }(3)

nr. 3
GROOVY BEANS
class Book {

String title

String description

}



def b1 = new Book()

b1.setTitle(“Anna Karenina”)

b1.description = “A very long book…”!
println b2.getDescription()

println b2.title



def b2 = new Book(title:”Anna Karenina”)

println b2.title
ALTRO SUI GROOVY BEANS
• Annotation based AST transformation (groovy.transform.*):!
• @Immutable (read only bean)!
• @ToString(includeNames=true, excludes=‘description,year’)!
• @EqualsAndHashCode!
• @Canonical (@ToString + @EqualsAndHashCode)!
• @TupleConstructor -> new Book(“Anna Karenina”, “Very long
book…”)!
• @AutoClone(style=AutoCloneStyle.COPY_CONSTRUCTOR)



def book1 = new Book(title:”Anna Karenina”)

def book2 = book1.clone()

assert book1.title == book2.title!
• AutoCloneStyle.SERIALIZABLE se implementa Serializable

ALTRE COSE BELLE
• methodMissing e propertyMissing per gestire
accessi a proprietà o metodi mancanti
• supporto nativo per markup XML, Json (Slurper e
Builder)
• conversioni bean in xml e json
• ExpandoMetaClass
• built-in memoize
DSL

DOMAIN SPECIFIC LANGUAGE
• Linguaggio di programmazione dedicato ad uno
specifico dominio (contrapposto a “general-purpose”)
• statistica (R e S)
• programmazione matriciale (Mata)
• Logo
• SQL
• …
DEFINIRE UN DSL IN GROOVY
Combinazione di tre punti chiave:
• fluent API
• embedded shell
• “specificità” del linguaggio
FLUENT API
È un implementazione di un API “method chaining”,
ovvero che permette chiamate di metodi “a catena”.
Es. JavaFX
Scene scene = SceneBuilder.create().width(516).height(387)

! .root(

! ! GroupBuilder.create().children(

! ! ! ImageViewBuilder.create().image(new Image(“..”)),

! ! ! [omissam]

! ! ).build()).build();
EMBEDING GROOVY IN JAVA
// Semplice esecuzione di codice Groovy!
GroovyShell shell = new GroovyShell();

String groovyCode = “println ‘Hello ’ + ‘Groovy’”;

String out = shell.evaluate(groovyCode);
// Esecuzione codice Groovy con variabile embeddata!
Book myBook = new Book();

myBook.setTitle(“Anna Karenina”);!
Binding binding = new Binding();

binding.setVariable(“book”, myBook);

String groovyCode = “println ‘Reading ‘ + book.title”;

GroovyShell shell = new GroovyShell(binding);

String out = shell.evaluate(groovyCode);
SPECIFICITÀ DI GROOVY
• le chiamate di metodi possono omettere le parentesi
• scriptBaseClass: la classe script base che rappresenta il contesto
di esecuzione dello script
• ImportCustomizer: importazione diretta nello script di classi e
package (anche *)
• SecureASTCustomizer: gestione della sicurezza (es. liste
bianche/nere)
• ASTTransformationCustomizer: per aggiungere
automaticamente annotazioni di trasformazione ai metodi
ESEMPIO SEMPLICE
Voglio creare un DSL in grado di eseguire:
compute 4 plus 3 plus 2 minus 1 print total!
• Una classe che implementa i metodi di linguaggio (compute, plus, minus, etc) come API
fluent
• Una classe astratta come base dello script groovy (si occuperà di proxare i metodi sullo
script)
• Un enum per le costanti (es. total)
• GroovyShell con:
• binding della classe linguaggio
• classe base astratta (vedi sopra)
• importazione custom delle costanti (vedi sopra)
Vediamo in pratica come procedere! (sorry, no slides here…)
LA CLASSE DI LINGUAGGIO
class Language {

Integer tot;

def compute(Integer a){

tot=a

this

}

def plus(Integer a){

tot += a

this

}

def minus(Integer a){

tot -= a

this

}

def print(Consts c){

tot

}

}
LA SCRIPTBASE E LA COSTANTE
abstract class AbstractScriptBaseClass extends Script{

def compute(Integer a){

this.lang.compute(a)

}

def plus(Integer a){

this.lang.plus(a)

}

def minus(Integer a){

this.lang.minus(a)

}

def print(String t){

this.lang.print(t)

}

}
public enum Consts {

total

}
TESTIAMO L’API
void testAPI() {



Language lang = new Language()

String total = "total"



// test API con sintassi tradizionale

Integer tot1 = lang.compute(4).plus(3).plus(2).minus(1).print(total)



// test API omettendo le parentesi

Integer tot2 = lang.compute 4 plus 3 plus 2 minus 1 print total



assert tot1 == 8

assert tot2 == 8



}
TESTIAMO IL DSL
void testShell() {



// il codice scritto nel DSL

def code = "compute 4 plus 3 plus 2 minus 1 print total"



Language lang = new Language()

Binding binding = new Binding();

binding.setVariable("lang", lang)



CompilerConfiguration conf = new CompilerConfiguration()

conf.scriptBaseClass = AbstractScriptBaseClass.class.name



ImportCustomizer imports = new ImportCustomizer()

imports.addStaticStars(Consts.name)

conf.addCompilationCustomizers(imports)



GroovyShell shell = new GroovyShell(binding, conf)

Integer tot = (Integer) shell.evaluate(code)



assert tot == 8

}
ESEMPIO MENO SEMPLICE
Un DSL per definire e risolvere problemi di geometria piana euclidea

(https://github.com/tizianolattisi/peg)
create triangle name "ABC"

extend "AC" to "D" with measure:"BC"

extend "BC" to "E" with measure:"AC"

create segment name "ED"

extend "DE" to "H"

extend "AB" to "H"

apply "10.8" on "ad", "bc" //angoli opposti

apply "10.3" on "CED", "ABC"

apply "10.6" on "ABC", "cba", "CED", "edc"

create segment name "BD"

apply "10.10" on "BCD", "BC", "CD"
–Tiziano Lattisi
“Grazie a tutti!”.

Weitere ähnliche Inhalte

Andere mochten auch

(E book pdf) thinking in patterns with java
(E book   pdf) thinking in patterns with java(E book   pdf) thinking in patterns with java
(E book pdf) thinking in patterns with javaRaffaella D'angelo
 
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"Expolink
 
(Ebook pdf) java programming language basics
(Ebook pdf)   java programming language basics(Ebook pdf)   java programming language basics
(Ebook pdf) java programming language basicsRaffaella D'angelo
 
Java Programming Language
Java Programming LanguageJava Programming Language
Java Programming LanguagePasquale Paola
 
Java e il paradigma a oggetti v2
Java e il paradigma a oggetti v2Java e il paradigma a oggetti v2
Java e il paradigma a oggetti v2cinziabb
 
Java e il paradigma a oggetti
Java e il paradigma a oggettiJava e il paradigma a oggetti
Java e il paradigma a oggetticinziabb
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
Programmazione a oggetti tramite la macchina del caffé (1/3)
Programmazione a oggetti tramite la macchina del caffé (1/3)Programmazione a oggetti tramite la macchina del caffé (1/3)
Programmazione a oggetti tramite la macchina del caffé (1/3)Marcello Missiroli
 
Python nel primo biennio della scuola superiore
Python nel primo biennio della scuola superiorePython nel primo biennio della scuola superiore
Python nel primo biennio della scuola superioreguestc11532
 
Programmazione ad oggetti
Programmazione ad oggettiProgrammazione ad oggetti
Programmazione ad oggettiAnna_1969
 
Sviluppare applicazioni mobile native in html e java script
Sviluppare applicazioni mobile native in html e java scriptSviluppare applicazioni mobile native in html e java script
Sviluppare applicazioni mobile native in html e java scriptFabio Franzini
 
Programmazione ad oggetti
Programmazione ad oggettiProgrammazione ad oggetti
Programmazione ad oggettimariacaporale
 
Tesina Maturità 2012-2013
Tesina Maturità 2012-2013 Tesina Maturità 2012-2013
Tesina Maturità 2012-2013 Michele Loda
 
(E book ita) java introduzione alla programmazione orientata ad oggetti in ...
(E book ita) java   introduzione alla programmazione orientata ad oggetti in ...(E book ita) java   introduzione alla programmazione orientata ad oggetti in ...
(E book ita) java introduzione alla programmazione orientata ad oggetti in ...Raffaella D'angelo
 

Andere mochten auch (20)

Pensiero Orientato Agli Oggetti
Pensiero Orientato Agli OggettiPensiero Orientato Agli Oggetti
Pensiero Orientato Agli Oggetti
 
Java
JavaJava
Java
 
Java 01
Java 01Java 01
Java 01
 
(E book pdf) thinking in patterns with java
(E book   pdf) thinking in patterns with java(E book   pdf) thinking in patterns with java
(E book pdf) thinking in patterns with java
 
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"
АКТИВ. Владимир Иванов. "Как помочь Вини Пуху и сохранить рассудок"
 
Linguaggio di programmazione java - Scheda corso LEN
Linguaggio di programmazione java - Scheda corso LENLinguaggio di programmazione java - Scheda corso LEN
Linguaggio di programmazione java - Scheda corso LEN
 
(Ebook pdf) java programming language basics
(Ebook pdf)   java programming language basics(Ebook pdf)   java programming language basics
(Ebook pdf) java programming language basics
 
Informatica di base
Informatica di baseInformatica di base
Informatica di base
 
OOP Java
OOP JavaOOP Java
OOP Java
 
Java Programming Language
Java Programming LanguageJava Programming Language
Java Programming Language
 
Java e il paradigma a oggetti v2
Java e il paradigma a oggetti v2Java e il paradigma a oggetti v2
Java e il paradigma a oggetti v2
 
Java e il paradigma a oggetti
Java e il paradigma a oggettiJava e il paradigma a oggetti
Java e il paradigma a oggetti
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Programmazione a oggetti tramite la macchina del caffé (1/3)
Programmazione a oggetti tramite la macchina del caffé (1/3)Programmazione a oggetti tramite la macchina del caffé (1/3)
Programmazione a oggetti tramite la macchina del caffé (1/3)
 
Python nel primo biennio della scuola superiore
Python nel primo biennio della scuola superiorePython nel primo biennio della scuola superiore
Python nel primo biennio della scuola superiore
 
Programmazione ad oggetti
Programmazione ad oggettiProgrammazione ad oggetti
Programmazione ad oggetti
 
Sviluppare applicazioni mobile native in html e java script
Sviluppare applicazioni mobile native in html e java scriptSviluppare applicazioni mobile native in html e java script
Sviluppare applicazioni mobile native in html e java script
 
Programmazione ad oggetti
Programmazione ad oggettiProgrammazione ad oggetti
Programmazione ad oggetti
 
Tesina Maturità 2012-2013
Tesina Maturità 2012-2013 Tesina Maturità 2012-2013
Tesina Maturità 2012-2013
 
(E book ita) java introduzione alla programmazione orientata ad oggetti in ...
(E book ita) java   introduzione alla programmazione orientata ad oggetti in ...(E book ita) java   introduzione alla programmazione orientata ad oggetti in ...
(E book ita) java introduzione alla programmazione orientata ad oggetti in ...
 

Ähnlich wie Groovy e Domain Specific Languages

Introduzione a TypeScript
Introduzione a TypeScriptIntroduzione a TypeScript
Introduzione a TypeScriptSinergia Totale
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritornolordarthas
 
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeo
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore RomeoHTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeo
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeomarcocasario
 
Codemotion 2012 creare un proprio linguaggio di programmazione
Codemotion 2012 creare un proprio linguaggio di programmazioneCodemotion 2012 creare un proprio linguaggio di programmazione
Codemotion 2012 creare un proprio linguaggio di programmazioneGabriele Guizzardi
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsJUG Genova
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourserik0
 
DotNetToscana - Sessione TypeScript
DotNetToscana - Sessione TypeScriptDotNetToscana - Sessione TypeScript
DotNetToscana - Sessione TypeScriptSinergia Totale
 
Web base-03-js-numeri stringearray
Web base-03-js-numeri stringearrayWeb base-03-js-numeri stringearray
Web base-03-js-numeri stringearrayStudiabo
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@UninaNaLUG
 
Javascript avanzato: sfruttare al massimo il web
Javascript avanzato: sfruttare al massimo il webJavascript avanzato: sfruttare al massimo il web
Javascript avanzato: sfruttare al massimo il webRoberto Messora
 
Al telefono con Adhearsion e Ruby
Al telefono con Adhearsion e RubyAl telefono con Adhearsion e Ruby
Al telefono con Adhearsion e RubyLuca Pradovera
 
Web base - Javascript (Node.js): Elementi di base
Web base - Javascript (Node.js): Elementi di baseWeb base - Javascript (Node.js): Elementi di base
Web base - Javascript (Node.js): Elementi di baseAnnalisa Vignoli
 
Functional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni LambdaFunctional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni LambdaEzio Sperduto, PhD
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewFrancesco Sciuti
 

Ähnlich wie Groovy e Domain Specific Languages (20)

Introduzione a TypeScript
Introduzione a TypeScriptIntroduzione a TypeScript
Introduzione a TypeScript
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritorno
 
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeo
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore RomeoHTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeo
HTML5 Italy: Mai più CSS, fogli di stile moderni con LESS - Salvatore Romeo
 
Codemotion 2012 creare un proprio linguaggio di programmazione
Codemotion 2012 creare un proprio linguaggio di programmazioneCodemotion 2012 creare un proprio linguaggio di programmazione
Codemotion 2012 creare un proprio linguaggio di programmazione
 
Vb.Net
Vb.NetVb.Net
Vb.Net
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMs
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourse
 
Mini Corso Java - Parte 1
Mini Corso Java - Parte 1Mini Corso Java - Parte 1
Mini Corso Java - Parte 1
 
DotNetToscana - Sessione TypeScript
DotNetToscana - Sessione TypeScriptDotNetToscana - Sessione TypeScript
DotNetToscana - Sessione TypeScript
 
Web base-03-js-numeri stringearray
Web base-03-js-numeri stringearrayWeb base-03-js-numeri stringearray
Web base-03-js-numeri stringearray
 
JOSM per “ninja”
JOSM per “ninja”JOSM per “ninja”
JOSM per “ninja”
 
Linux@Unina
Linux@UninaLinux@Unina
Linux@Unina
 
Javascript avanzato: sfruttare al massimo il web
Javascript avanzato: sfruttare al massimo il webJavascript avanzato: sfruttare al massimo il web
Javascript avanzato: sfruttare al massimo il web
 
Al telefono con Adhearsion e Ruby
Al telefono con Adhearsion e RubyAl telefono con Adhearsion e Ruby
Al telefono con Adhearsion e Ruby
 
REST con Jersey
REST con JerseyREST con Jersey
REST con Jersey
 
Web base - Javascript (Node.js): Elementi di base
Web base - Javascript (Node.js): Elementi di baseWeb base - Javascript (Node.js): Elementi di base
Web base - Javascript (Node.js): Elementi di base
 
Functional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni LambdaFunctional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni Lambda
 
Grillo
GrilloGrillo
Grillo
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Jug 30 10 04 Jdo
Jug 30 10 04 JdoJug 30 10 04 Jdo
Jug 30 10 04 Jdo
 

Mehr von Tiziano Lattisi

Mehr von Tiziano Lattisi (6)

JugTAAS ReSTful
JugTAAS ReSTfulJugTAAS ReSTful
JugTAAS ReSTful
 
ZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFXZoeFX: un framework MVC per JavaFX
ZoeFX: un framework MVC per JavaFX
 
JavaFX2: una panoramica
JavaFX2: una panoramicaJavaFX2: una panoramica
JavaFX2: una panoramica
 
VCS - DVCS - GIT-FLOW
VCS - DVCS - GIT-FLOWVCS - DVCS - GIT-FLOW
VCS - DVCS - GIT-FLOW
 
JPA2 - a brief intro
JPA2 - a brief introJPA2 - a brief intro
JPA2 - a brief intro
 
PyPaPi Qt Java Framework
PyPaPi Qt Java FrameworkPyPaPi Qt Java Framework
PyPaPi Qt Java Framework
 

Groovy e Domain Specific Languages

  • 1. GROOVY E DSL BY TIZIANO LATTISI
  • 2. INDICE • cos’è Groovy? • caratteristiche interessanti (a mio giudizio), in ordine arbitrariamente sparso • cos’è un DSL? • caratteristiche che rendono Groovy adatto a costruire un DSL • un esempio semplice (lo facciamo al volo) • un esempio meno semplice (non lo facciamo al volo) nota: in parallelo vedremo esempi
  • 3. COS’È GROOVY (PARTE 1)? • linguaggio per la JVM alternativo a Java • ispirato a: Ruby, Python, Smalltalk • consente compilazione dinamica, ma può anche generare bytecode • tipizzazione forte dinamica • closure
  • 4. COMMAND-LINE GROOVY HELLO GROOVY • $ groovy -e “println ‘Hello Groovy’”! • $ echo “println ‘Hello Groovy’” > hello.groovy
 $ groovy hello.groovy! • $ groovy -Dmsg=Groovy -e “println ‘Hello ‘ + System.getProperty(‘msg’)”
  • 5. COMMAND-LINE GROOVY SWITCH -N -P -I • $ printf “1n2” > data.txt
 $ groovy -n -e “println line.toLong()*2” data.txt
 2
 4! • $ groovy -i.bak —n -p -e “line.toLong()*2” data.txt
 $ cat data.txt
 2
 4
 $ cat data.txt.bak
 1
 2

  • 6. COMMAND-LINE GROOVY SWITCH -L • $ groovy -l 1234 -e “if(line==‘DATE’){println new Date()}”
 Groovy is listening on port 1234
 
 $ telnet localhost 1234
 Connect to localhost.
 Escape character is ‘^]’.
 DATE
 Mon Mar 17 21:38:49 CET 2014! • $ groovy -l 80 SimpleWebServer.groovy
 
 Esempio nei sorgenti Groovy: serve i file di una cartella come webserver

  • 7. COS’È GROOVY (PARTE 2)? • è possibile usare direttamente l’API Java • accetta (salvo alcune eccezioni) anche sintassi Java (es. {1,2,3,4} non è array, ma [1,2,3,4] è un ArrayList) • import automatico (di convenienza) di alcune classi Java (es. java.io, java.lang, java.net, java.util…) • println -> System.out.println • parentesi opzionali nella chiamata a metodi • notazione breve per getter e setter (o.field -> o.getField()) • ; opzionale (salvo alcune eccezioni) • return opzionale (viene restituita l’ultima valutazione) • this usata in contesti statici punta alla classe
  • 8. COS’È GROOVY (PARTE 3)? • GString interpolation: “Hello ${name}” • Lazily interpolation (eval in conversione a String): “Nr. ${-> i}” • == -> equals, equals -> is: non più “a != null && a.equals()” !! • in: è un operatore basato su contains(): 3 in [1,2,3,4] • sintassi nativa per alcune strutture dati: [1,2,3] list, [TN:’Trento’, BZ:’Bolzano] map, 1..10 range • contesti booleani: if( myString!=null && myString.length>0 ){} -> if(myString){} • safe-dereferencing: email?.destinatario?.indirizzo • costrutto and-or (Elvis operator):
 def result = name != null ? name : “Unknow”
  • 9. FOR E FOR EACH • for (int i=0; i<n; i++) { … }! • for (i in 0..n-1) { … }! • for (i in 0..<n) { … }! • n.times { … }
 • (1..5).each { println “nr. $it” }! • 1..5 instanceof List! • { println “nr. $it” }(3)
 nr. 3
  • 10. GROOVY BEANS class Book {
 String title
 String description
 }
 
 def b1 = new Book()
 b1.setTitle(“Anna Karenina”)
 b1.description = “A very long book…”! println b2.getDescription()
 println b2.title
 
 def b2 = new Book(title:”Anna Karenina”)
 println b2.title
  • 11. ALTRO SUI GROOVY BEANS • Annotation based AST transformation (groovy.transform.*):! • @Immutable (read only bean)! • @ToString(includeNames=true, excludes=‘description,year’)! • @EqualsAndHashCode! • @Canonical (@ToString + @EqualsAndHashCode)! • @TupleConstructor -> new Book(“Anna Karenina”, “Very long book…”)! • @AutoClone(style=AutoCloneStyle.COPY_CONSTRUCTOR)
 
 def book1 = new Book(title:”Anna Karenina”)
 def book2 = book1.clone()
 assert book1.title == book2.title! • AutoCloneStyle.SERIALIZABLE se implementa Serializable

  • 12. ALTRE COSE BELLE • methodMissing e propertyMissing per gestire accessi a proprietà o metodi mancanti • supporto nativo per markup XML, Json (Slurper e Builder) • conversioni bean in xml e json • ExpandoMetaClass • built-in memoize
  • 13. DSL
 DOMAIN SPECIFIC LANGUAGE • Linguaggio di programmazione dedicato ad uno specifico dominio (contrapposto a “general-purpose”) • statistica (R e S) • programmazione matriciale (Mata) • Logo • SQL • …
  • 14. DEFINIRE UN DSL IN GROOVY Combinazione di tre punti chiave: • fluent API • embedded shell • “specificità” del linguaggio
  • 15. FLUENT API È un implementazione di un API “method chaining”, ovvero che permette chiamate di metodi “a catena”. Es. JavaFX Scene scene = SceneBuilder.create().width(516).height(387)
 ! .root(
 ! ! GroupBuilder.create().children(
 ! ! ! ImageViewBuilder.create().image(new Image(“..”)),
 ! ! ! [omissam]
 ! ! ).build()).build();
  • 16. EMBEDING GROOVY IN JAVA // Semplice esecuzione di codice Groovy! GroovyShell shell = new GroovyShell();
 String groovyCode = “println ‘Hello ’ + ‘Groovy’”;
 String out = shell.evaluate(groovyCode); // Esecuzione codice Groovy con variabile embeddata! Book myBook = new Book();
 myBook.setTitle(“Anna Karenina”);! Binding binding = new Binding();
 binding.setVariable(“book”, myBook);
 String groovyCode = “println ‘Reading ‘ + book.title”;
 GroovyShell shell = new GroovyShell(binding);
 String out = shell.evaluate(groovyCode);
  • 17. SPECIFICITÀ DI GROOVY • le chiamate di metodi possono omettere le parentesi • scriptBaseClass: la classe script base che rappresenta il contesto di esecuzione dello script • ImportCustomizer: importazione diretta nello script di classi e package (anche *) • SecureASTCustomizer: gestione della sicurezza (es. liste bianche/nere) • ASTTransformationCustomizer: per aggiungere automaticamente annotazioni di trasformazione ai metodi
  • 18. ESEMPIO SEMPLICE Voglio creare un DSL in grado di eseguire: compute 4 plus 3 plus 2 minus 1 print total! • Una classe che implementa i metodi di linguaggio (compute, plus, minus, etc) come API fluent • Una classe astratta come base dello script groovy (si occuperà di proxare i metodi sullo script) • Un enum per le costanti (es. total) • GroovyShell con: • binding della classe linguaggio • classe base astratta (vedi sopra) • importazione custom delle costanti (vedi sopra) Vediamo in pratica come procedere! (sorry, no slides here…)
  • 19. LA CLASSE DI LINGUAGGIO class Language {
 Integer tot;
 def compute(Integer a){
 tot=a
 this
 }
 def plus(Integer a){
 tot += a
 this
 }
 def minus(Integer a){
 tot -= a
 this
 }
 def print(Consts c){
 tot
 }
 }
  • 20. LA SCRIPTBASE E LA COSTANTE abstract class AbstractScriptBaseClass extends Script{
 def compute(Integer a){
 this.lang.compute(a)
 }
 def plus(Integer a){
 this.lang.plus(a)
 }
 def minus(Integer a){
 this.lang.minus(a)
 }
 def print(String t){
 this.lang.print(t)
 }
 } public enum Consts {
 total
 }
  • 21. TESTIAMO L’API void testAPI() {
 
 Language lang = new Language()
 String total = "total"
 
 // test API con sintassi tradizionale
 Integer tot1 = lang.compute(4).plus(3).plus(2).minus(1).print(total)
 
 // test API omettendo le parentesi
 Integer tot2 = lang.compute 4 plus 3 plus 2 minus 1 print total
 
 assert tot1 == 8
 assert tot2 == 8
 
 }
  • 22. TESTIAMO IL DSL void testShell() {
 
 // il codice scritto nel DSL
 def code = "compute 4 plus 3 plus 2 minus 1 print total"
 
 Language lang = new Language()
 Binding binding = new Binding();
 binding.setVariable("lang", lang)
 
 CompilerConfiguration conf = new CompilerConfiguration()
 conf.scriptBaseClass = AbstractScriptBaseClass.class.name
 
 ImportCustomizer imports = new ImportCustomizer()
 imports.addStaticStars(Consts.name)
 conf.addCompilationCustomizers(imports)
 
 GroovyShell shell = new GroovyShell(binding, conf)
 Integer tot = (Integer) shell.evaluate(code)
 
 assert tot == 8
 }
  • 23. ESEMPIO MENO SEMPLICE Un DSL per definire e risolvere problemi di geometria piana euclidea
 (https://github.com/tizianolattisi/peg) create triangle name "ABC"
 extend "AC" to "D" with measure:"BC"
 extend "BC" to "E" with measure:"AC"
 create segment name "ED"
 extend "DE" to "H"
 extend "AB" to "H"
 apply "10.8" on "ad", "bc" //angoli opposti
 apply "10.3" on "CED", "ABC"
 apply "10.6" on "ABC", "cba", "CED", "edc"
 create segment name "BD"
 apply "10.10" on "BCD", "BC", "CD"