Groovy: Ruby per i programmatori Java

 

Ieri, avevo pubblicato un post riguardo NetBeans e la beta della versione 6.5 in cui citavo le varie novità di questa , tra tutte queste una che meritava attenzione a mio modo di vedere era Groovy. Già lo hanno definito “ 2.0″, ma cos’è pochi lo sanno. Cercherò in questo articolo di spiegare cosa sia Groovy, confrontandolo con e cercando gli aspetti positivi. Lo sviluppo iniziale di Groovy risale al lontano 2003, quando James Strachan gettò le basi del progetto con un post sul suo blog. Successivamente, nel 2004, diventò una Specification Request, con id 241, questo è il motivo per cui a volte viene menzionato come JSR241. La 1.0 è stata rilasciata il 2 Gennaio 2007. L’ultima stabile è la 1.5.6 rilasciata il 25 Aprile 2008. Ma cos’è Groovy?

Groovy è un linguaggio di programmazione orientato agli oggetti nato con la pretesa di far avvicinare la robustezza di alla semplicità ed alla velocità di sviluppo dei linguaggi più moderni come Python, Ruby e i meno moderni Perl e SmallTalk. La particolarità è che stavolta non ci troviamo dinanzi all’ennesimo linguaggio di programmazione così come siamo abituati a considerare, bensì un linguaggio di programmazione per l’ambiente , ad esso alternativo e completamente interoperabile (o quasi). Possiamo includere codice in codice Groovy, di seguito entrambi verranno semi-compilati in bytecode per poi essere eseguito da qualsiasi JVM. Gli sviluppatori Groovy affermano che la curva di apprendimento per passare da a Groovy è prossima allo zero. Vediamo se è vero e vediamo se davvero lo sviluppo in Groovy è più agile. Quella che segue è una lista delle principali differenze, spero sia quanto più completa possibile, se mi è sfuggito qualcosa di interessante basta un commento:

Import di default

A differenza di , vengono importate di default una di librerie che sono:

.io.*
.lang.*
.math.BigDecimal
.math.BigInteger
.net.*
.util.*
groovy.lang.*
groovy.util.*

Array

Sebbene la sintassi sia molto simile a , non useremo le parentesi graffe per dichiarare un array, bensì le quadre:

int[] a = {1,2,3};   // Sintassi 
int[] a = [1,2,3];     // Sintassi Groovy

Ciclo for

Il ciclo for non può essere scritto come siamo abituati a fare, ma abbiamo delle sintassi alternative:

// Sintassi 
for (int i=0; i < len; i++) {...}

// Alternative Groovy
for (i in 0..len-1) {...}
for (i in 0..<len) {...}
len.times {...}

Per ora, non so se sia una scelta voluta, o dovuta a problemi di sviluppo, nella testata del for può essere aggiunta una sola variabile di incremento.

Liste

In una list è una collezione ordinata, come l’array ha un indice per ogni elemento ed ammette duplicati. Le principali implementazioni di list sono ArrayList, Vector e LinkedList. Qualsiasi implementazione vogliamo usare, in , va per l’appunto istanziata:

ArrayList list = new ArrayList(3);
list.add(5);
list.add(6);
list.add(7);
list.add(8);

In Groovy non abbiamo bisogno di crearle con new:

def list = [5, 6, 7, 8]

Supporto ai linguaggi di Markup

import groovy.xml.MarkupBuilder
    def myXMLDoc = new MarkupBuilder()
    myXMLDoc.workbook {
       worksheet(caption:"Employees") {
          row(fname:"John", lname:"McDoe")
          row(fname:"Nancy", lname:"Davolio")
       }
       worksheet(caption:"Products") {
          row(name:"Veeblefeetzer", id:"sku34510")
          row(name:"Prune Unit Zappa", id:"sku3a550")
       }
    }
    println myXMLDoc

produce in output:

<workbook>
  <worksheet caption='Employees'>
    <row fname="John" lname="McDoe" />
    <row fname="Nancy" lname="Davolio" />
  </worksheet>
  <worksheet caption='Products'>
    <row name="Veeblefeetzer" id="sku34510" />
    <row name="Prune Unit Zappa" id="sku3a550" />
  </worksheet>
</workbook>

Se avessimo voluto farlo in :

import .io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XMLFun {

        public static void main(String[] args) throws Exception {
                TransformerFactory factory = TransformerFactory.newInstance();
                factory.setAttribute("indent-number", 2);
                Transformer trans = factory.newTransformer();
                trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                trans.setOutputProperty(OutputKeys.INDENT, "yes");

                DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
                Document doc = docBuilder.newDocument();
                Element workbook = doc.createElement("workbook");
                doc.appendChild(workbook);
                Element worksheet = doc.createElement("worksheet");
                worksheet.setAttribute("caption", "Employees");
                workbook.appendChild(worksheet);
                Element row = doc.createElement("row");
                row.setAttribute("fname", "John");
                row.setAttribute("lname", "McDoe");
                worksheet.appendChild(row);
                row = doc.createElement("row");
                row.setAttribute("fname", "Nancy");
                row.setAttribute("lname", "Davolio");
                worksheet.appendChild(row);

                worksheet = doc.createElement("worksheet");
                worksheet.setAttribute("caption", "Products");
                workbook.appendChild(worksheet);
                row = doc.createElement("row");
                row.setAttribute("name", "Veeblefeetzer");
                row.setAttribute("id", "sku34510");
                worksheet.appendChild(row);
                row = doc.createElement("row");
                row.setAttribute("name", "Prune Unit Zappa");
                row.setAttribute("id", "sku3a550");
                worksheet.appendChild(row);

                StringWriter writer = new StringWriter();
                StreamResult out = new StreamResult(writer);
                DOMSource dsource = new DOMSource(doc);
                trans.transform(dsource, out);
                System.out.println(writer.toString());
        }
}

Altre differenze altrettanto importanti sono: la possibilità di non terminare le istruzioni con un punto e virgola, questo va fatto solo se scriviamo più istruzioni su una stessa riga; l’istruzione return non è obbligatoria; metodi e classi sono public di default; non c’è differenza tra eccezioni checked e unchecked; supporto nativo alle espressioni regolari; possibilità di tipizzazione statica o dinamica per variabili e metodi. Per maggiori informazioni consiglio di dare un’occhiata al sito ufficiale del progetto, http://groovy.codehaus.org/, dove possiamo trovare preziose informazioni e documenti che ho usato per creare questo articolo. Detto questo non resta che mostrare il classico “Hello .

class Greet {
  def name
  Greet(who) { name = who[0].toUpperCase() + who[1..-1] }
  def salute() { println "Hello $name!" }
}

g = new Greet('')  // create object
g.salute()               // Output "Hello !"

Sebbene le somiglianze con siano evidenti, è anche vero che per un programmatore esperto abituato con la sintassi è noiso per i primi tempi capire come scrivere il codice e magari fare continuamente riferimento alla documentazione per creare una classe, un metodo o un ciclo for. Nonostante tutto, penso che questo “spreco” di tempo iniziale sarà ben ripagato nel futuro. L’esempio del documento XML è quello più lampante di quanto può essere veloce programmare con Groovy.
Intanto la comunità sta apprezzando il progetto, tant’è che a corredo sono nati anche vari framework, Grails è il primo che mi viene in mente. Non resta dunque che iniziare a provare…

Tags: , , , , , , , , , , , , ,

Post correlati

 

Discussion

What do you think? Leave a comment. Alternatively, write a post on your own weblog; this blog accepts trackbacks [trackback url].

Leave a Reply