Groovy è un linguaggio basato su Java adatto alla programmazione agile. Ha molte caratteristiche in comune con Python, Ruby, Perl, Smalltalk poiché, come questi, è un linguaggio di scripting orientato agli oggetti.
Groovy è pensato per aumentare la produttività, ovvero la velocità con cui si sviluppano applicazioni: riduce il codice necessario e semplifica l'accesso alle basi di dati. Integra tutti gli oggetti e le librerie Java e la compilazione produce file in formato bytecode che si possono utilizzare in ogni situazione in cui si può usare Java.
Groovy può essere inoltre utilizzato come linguaggio di scripting da console e quasi tutti i costrutti Java sono validi anche in Groovy.
La sua potenza e semplicità hanno permesso lo sviluppo di Grails, un ottimo framework per lo sviluppo rapido di applicazioni web. Anche il nome lo dovrebbe suggerire: Groovy sta a Grails come Ruby sta a Rails.
La prima versione del linguaggio, la 1.0, è stata rilasciata da James Strachan il 2 gennaio 2007. Da quel momento sono state rilasciate varie versioni, fino all'attuale 1.7, ultima versione stabile scaricabile dal sito del progetto. Groovy, naturalmente, può essere installato su qualsiasi sistema con supporto la Java Virtual Machine.
Tra le altre caratteristiche di Groovy:
- Consente la modifica a runtime di classi e metodi, ad esempio definendo un nuovo metodo di classe
- Le istruzioni sono separate dal carattere di nuova linea, non è necessario inserire il carattere ';' alla fine della linea
- Gestisce le liste e le espressioni regolari come costrutti built-in nel linguaggio
Dalla prossima pagina esamineremo più a fondo i principali costrutti sintattici, come le Closures e la definizione di classi e e oggetti.
Principali costrutti sintattici: liste e mappe
Groovy supporta due importanti tipi di dati predefiniti: le liste e le mappe. Le liste sono utilizzate per la memorizzazione di insiemi ordinati di dati, ad esempio:
colleghi = ["Piero", "Lorenzo", "Davide", "Luigi"]
println colleghi[2]
Risultato: Davide
Il numero di elementi di una lista è ottenuto mediante il metodo size()
:
println colleghi.size()
Risultato: 4
Per "ciclare" gli elementi di una lista è utilizzato il metodo each()
:
res=""
colleghi.each({
res += it + ", "
})
println res
Risultato: Piero, Lorenzo, Davide, Luigi
Il corpo del metodo each()
è una chiusura, un costrutto di Groovy descritto nel prossimo paragrafo.
L'aggiunta di un elementi alla lista si esegue mediante l'istruzione:
colleghi[4]="Mirko"
println colleghi
Risultato: Piero, Lorenzo, Davide, Luigi, Mirko
L'altra struttura dati, la mappa, è utilizzata per memorizzare dizionari, cioé array contenenti coppie chiave/valore:
pagella = ["italiano":6, "matematica": 8, "informatica": 9, "storia": "impreparato"]
Notiamo che i valori memorizzati nella mappa possono essere di tipo diverso. L'accesso ai valori della mappa può essere fatto in due modi:
println pagella["matematica"]
e
println pagella.matematica
entrambi i comandi restituiscono 8.
L'aggiunta di un elemento alla mappa è effettuata come per la lista:
pagella["geografia"] = 5
Closures
Le chiusure (closures) sono costrutti sintattici caratteristici di Groovy. Le chiusure permettono di definire in modo conciso delle funzioni.
Esempio:
next = { x +1 }
next(3)
Risultato: 4
La potenza di queste istruzioni sta nel fatto che possono essere applicate ad interi array mediante una sintassi molto compatta:
[1,2,3,4,5].collect(next)
Risultato: [2,3,4,5,6]
Si possono creare delle chiusure con parametri. Ad esempio, riprendendo la mappa pagella definita in precedenza:
stampaPagella = { materia, voto -> println "Materia: "+materia + " Voto:" + voto }
pagella.each(stampaPagella)
Risultato: Materia: italiano Voto:6 Materia: matematica Voto: 8 Materia: informatica Voto: 9 Materia: storia Voto: impreparato
Classi ed oggetti
Tutto in Groovy è un oggetto. Per esempio, la definizione
int x = 0
è la forma abbreviata di
Integer x = new Integer(0)
Il programmatore Java si accorgerà che, in questo linguaggio, la prima versione venga considerata come una dichiarazione di una variabile di tipo primitivo int
, mentre la seconda di un oggetto integer
.
Ma vediamo come possiamo definire e usare gli oggetti in Groovy. La sintassi per la definizione di classi ed oggetti è molto simile a quella di Java:
package it.html.groovy
class Esempio1{
static void main(args){
def stringhe = ["Primo","esempio","di"," classe","Groovy"]
stringhe.each{ println it+ " " }
}
Notiamo che la definizione della variabile stringhe è preceduta dalla parola chiave def
. def
sostituisce il tipo della variabile e indica che il parser Groovy deve inferire il tipo (nell'esempio sarà inferito String[]
).
Vediamo un altro esempio:
package it.html.groovy
public class Persona{
String nome
String cognome
static void main(args){
Persona p = new Persona()
p.setNome("Fabio")
p.setCognome("Marcone")
println p.nome +" "+p.cognome
}
}
Possiamo notare come i metodi setNome()
e setCognome()
vengano definiti implicitamente da Groovy, sollevando il programmatore da questo ripetitivo compito.
Differenze tra Groovy e Java
Come abbiamo già detto, è possibile utilizzare la sintassi Java in Groovy; esistono però delle differenze sintattiche e semantiche tra i due linguaggi. Per comodità le riportiamo sinteticamente nell'elenco che segue:
- operatore ==
- In Java: ha significati diversi, per i tipi primitivi indica uguaglianza (di valori) mentre per gli oggetti indica identità (stesso oggetto);
- In Groovy: è sempre l'uguaglianza di valori (
equals()
in Java), anche perché non esistono in Groovy i tipi primitivi. Per indicare l'identità di due oggetti si utilizza il metodois();
- La stringa
in
non può essere usata come nome di variabile in quanto è una parola chiave; - Cicli e contatori:
- In Java:
for (int i=0; i < len; i++) {...}
- In Groovy:
len.times {...}
- In Java:
- Il carattere "punto e virgola" che in Java è obbligatorio per indicare la fine di un'istruzione, in Groovy è opzionale;
- L'istruzione
return
alla fine dei metodi è opzionale; - La parola chiave
this
può essere usata anche in contesti statici e indica la classe in oggetto; - Metodi e classi hanno visibilità pubblica di default;
- Groovy non supporta la definizione di classi annidate;
- Groovy è un linguaggio a tipizzazione dinamica, quindi non mostra errori in fase di compilazione nel caso utilizziamo membri non dichiarati o passati ai metodi argomenti di tipo errato.
Possibilità di utilizzo
Groovy è un linguaggio di programmazione adatto a diversi tipi di utilizzo (multi purpose) che può essere utilizzato in molteplici contesti in quanto:
- Può essere impiegato in alcuni componenti di progetti scritti in Java poiché mediante le chiusure e la sua sintassi compatta permette di esprimere comportamenti difficilmente esprimibili in Java.
- è adatto per rappresentare e gestire strutture dati gerarchiche in quanto le sue strutture dati, liste e mappe e le sue api, ad esempio i costruttori (builders) che implementano il design pattern builders, rendono semplice la manipolazione di file xml o strutture gerarchiche di altro tipo.
- Non necessita di ambienti di esecuzioni particolari in quanto la sola precondizione di utilizzo è la presenza della virtual machine Java, il che lo rende facilmente impiegabile in molti scenari pratici e su sistemi operativi differenti.