Ruby

I parte: introduzione al linguaggiodi

Inizia oggi una serie di articoli che descrivono gli aspetti principali del linguaggio Ruby e che andranno a focalizzarsi su Rails (il Web Application Framework più diffuso e potente del linguaggio) che implementa il pattern MVC, ma che contiene anche uno strumento ORM molto interessante. L‘intento è quello di toccare vari aspetti, dalla sintassi del linguaggio Ruby all‘utilizzo e codifica del framework, evidenziandone peculiarità, pregi ed eventualmente anche limiti.

Introduzione

Inizia oggi una serie dedicata a Ruby.

Si tratta di un‘ interessante tecnologia nel panorama internazionale che merita, a nostro avviso, una attenta analisi da parte di chi desidera disporre di un quadro completo delle opportunità  disponibili in ambito "sviluppo applicazioni".

Una scelta snella, produttiva, portabile e free "...free of charge, but also freedom to use, copy, modify, and distribute it...".

Nella nostra serie di articoli abbiamo intenzione di toccare vari aspetti, dai primi passi della configurazione dell‘ambiente, allo sviluppo web con il framework Rails, passando per Unit Testing, Duck Typing e altre caratteristiche del linguaggio quali Regular Expression, Moduli, ecc.

Un po‘ di Storia

Ruby è un linguaggio con caratteristiche singolari. La più interessante forse è il fatto che sia per la maggior parte il risultato del lavoro di una sola persona, il giapponese Yukihiro Matsumoto, o più confidenzialmente "Matz" che ha iniziato a sviluppare il linguaggio fin dal 1993, quindi ben prima che Java apparisse all‘orizzonte (all‘epoca era ancora un progetto interno Sun denominato Oak).

Successivamente, mentre Java si diffondeva a macchia d‘olio, sospinto da Sun e dalla diffusione del World Wide Web, Ruby cresceva lentamente, conquistandosi a poco a poco una schiera di utenti appassionati. Nell‘ultimo anno il numero di progetti basati su Ruby è cresciuto notevolmente, grazie anche alla diffusione del framework Rails, che propone un paradigma di programmazione web drasticamente semplificato (e soprattutto più produttivo) rispetto alla programmazione Java mainstream per il web.

Rails a parte, è interessante notare che Ruby è considerato in questo momento il linguaggio con cui è più piacevole programmare. La coerenza della sintassi, la sua pulizia e la sua intrinseca semplicità  sono infatti le caratteristiche che più spesso vengono lodate dai programmatori Ruby.

Il primo programma "hello world" in Ruby viene alla luce nell‘estate del 1993. La prima "alpha version" viene rilasciata a dicembre del 1994.

Da quel momento è iniziato un notevole interesse per il linguaggio tanto che attualmente è uno dei pochi esempi di tecnologia software proveniente dall‘oriente e che si è affermata in tutto il mondo.

Perchè Ruby

Supponiamo di voler scrivere applicazioni (in particolare applicazioni web) solide e facilmente manutenibili.

Abbiamo varie alternative tra cui muoverci. Cerchiamo di valutarle insieme.

Java, nelle sue varie interpretazioni in forma di framework quali Struts, Java Server Faces o Tapestry, è un opzione sicuramente valida e percorribile. Il punto debole della maggior parte dei presentation frameworks in Java è tuttavia dato dal tempo di apprendimento necessario ad essere produttivi, per una serie di motivi:

  • i frameworks si evolvono, spesso più velocemente del supporto che può essere offerto dall‘IDE
  • spesso da progetto a progetto il framework cambia
  • i framework sono complessi e necessitano la familiarità  con il pattern MVC, con XML, HTML, JSP, Tag Libraries, Servlet, etc.

Il risultato ottenuto sarebbe un‘ applicazione solida, ma, probabilmente non lo otterremmo agevolemente e in maniera rapida. Inoltre il costo di manutenzione risulterebbe essere non trascurabile.

Nell‘ eventualità  in cui il contesto renda necessario il ricorso ad applicazioni J2EE di una certa complessità , la scelta risulterebbe essere quasi obbligata nell‘utilizzo di Java Enterprise. Nelle altre situazioni possiamo valutare ulteriori possibilità .

Al fine di ridurre i tempi iniziali di sviluppo potremmo optare per PHP.

La sistematizzazione del codice in un linguaggio di scripting di questo tipo (anche se OO con PHP5), pressochè privo di validi framework realmente MVC, uniti alla non completa disponibilità  di strumenti a supporto delle varie fasi di sviluppo (che necessariamente ci impongono self-discipline nelle varie fasi del processo) ci fanno ponderare con attenzione tale scelta.

O comunque ci fanno relegare tale scelta ad alcune situazioni particolari come p.e. estensione della miriade di applicazioni Open Source disponibili.

Potremmo optare per alternative sicuramente molto meno diffuse, e non proprio Object-Oriented, quali Phyton o Perl. Oppure... potremmo a questo punto valutare di prendere seriamente in considerazione l‘ipotesi Ruby.

Uno dei punti di forza di Ruby è senza dubbio velocità  di sviluppo e la semplicità  di manutenzione

Le parole di Mike Clark a riguardo "...programming in any language other than Ruby will feel like you‘re pushing the rope"testimoniano la facilità  della programmazione in Ruby.

Nel prosieguo cercheremo di fornire esaustive delucidazioni e di spiegare il perchè di tale affermazione.

Caratteristiche del linguaggio (da Java Developer)

Ruby è un linguaggio Object Oriented. Linguaggio semplice da comprendere e da programmare.

Qualsiasi cosa viene manipolata in Ruby è un oggetto e lo stesso dicasi del risultato della manipolazione.

Tanto per fare un esempio il numero 1 è un istanza della classe Fixnum.

Uno sviluppatore Java si dovrebbe trovare abbastanza a proprio agio con Ruby visto che si tratta di linguaggio OO con una serie di caratteristiche che lo fanno sentire particolarmente a proprio agio, (mi riferisco alla presenza di classi, ereditarietà , variabili d‘istanza e di classe, ecc.). Ciò che però deve essere allontanato dalla mente del programmatore Java è la tentazione di utilizzare un Java-like coding style, cosa che, soprattutto all‘inizio, risulta essere un‘ attrattiva piuttosto forte.

Prima di passare alla fase di codifica facciamo un brutale, e ovviamente non esaustivo, elenco di caratteristiche di Ruby in un‘ ottica di confronto con Java. Questo ci servirà  ad inquadrarlo avendo come punto di partenza la conoscenza del linguaggio di Sun.

Premettendo che Java è un linguaggio maturo, testato ma anche molto "verboso", ciò che si noterà  abbastanza rapidamente passando a Ruby è la riduzione drastica delle righe di codice scritto.

Elenchiamo le caratteristiche principali che accomunano o differenziano i due linguaggi.

Ruby, come Java

  • è un linguaggio interpretato
  • è un linguaggio OO (Object Oriented)
  • dispone di un Garbage Collector per la gestione della memoria
  • è portabile ed è utilizzabile con i principali sistemi operativi
  • ha oggetti fortemente "tipati"
  • dispone di uno strumento di documentazione del sorgente (RDoc) molto simile a JavaDoc
  • ha "accessori" publici, protetti e privati, anche se il loro significato è diverso dai più comuni linguaggi OO e da Java

A differenza di Java

  • il codice non necessità  di compilazione.
  • non è presente la dichiarazione del tipo
  • è presente la keyword end per terminare classi, metodi e strutture in genere
  • non sono presenti primitive
  • non sono presenti interfacce, ma dispone di mix-in
  • non è possibile fare overloading dei metodi
  • ma soprattutto è "dynamically typed". e vedremo in seguito quale è l‘impatto di questa ultima caratteristica.

Teniamo a mente quanto sopra riportato e passiamo all‘installazione dell‘ambiente, operazione preliminare per arrivare alla codifica.

Installiamo Ruby

Ruby è molto semplice da installare sotto qualsiasi piattaforma (Windows, Linux, Mac OS X, ecc).

A volte è addirittura disponibile nei pacchetti del sistema operativo (questo è il caso di alcune distribuzioni Linux e Mac OS X).

Nelle altre situazioni è necessario effettuare il download della distribuzione binaria e procedere quindi alla sua installazione.

In ambiente Windows è disponibile l‘installer al link http://rubyinstaller.rubyforge.org.

L‘installazione risulta essere molto rapida e consente di avere a disposizione non solo l‘interprete per Ruby, ma anche Ruby Gem e FreeRIDE, un IDE basico per gestire progetti.

Per alcune distribuzioni Linux "RPM-based" si può trovare a http://rpmfind.net, mentre per distribuzioni basate su dpkg Debian si può utilizzare il gestore di pacchetti apt per effettuare l‘installazione.

Ã? possibile anche, per chi non si volesse perdere le ultimissime novità , effettuare il download del source (da http://www.ruby-lang.org) ed effettuare la relativa compilazione ed installazione.

Irb

Merita una piccola citazione per l‘importanza che ricopre il suo utilizzo.

Irb è uno strumento che consente di immettere codice Ruby e visualizzare immediatamente il risultato dell‘esecuzione. Una sorta di scrapbook interattivo.

Viene installato automaticamente con l‘installazione base e risulta particolarmente utile per fare delle prove on-the-fly.

Running Ruby

Configurato l‘ambiente siamo pronti per eseguire programmi.

Creiamo l‘ Hello World del caso in un file helloworld.rb che conterrà 

puts "Hello World!!!"

e quindi lanciamo

ruby ./helloworld.rb

L‘output che otteniamo sarà 

Hello World!!!

La riduzione del codice necessari ad ottenere il risultato è decisamente considerevole!

Let‘s code

Scriviamo la nostra prima classe.

class Automobile
def initialize(marca, modello)
@marca=marca
@modello=modello
end
end

Creiamo una istanza della nostra prima classe

automobile = Automobile.new("Honda","Jazz")

Aggiungiamo un primo metodo alla classe

	def componi_nome
"Auto: #@marca--#@modello"
end

Quindi invochiamo il metodo

nome_auto=(automobile.componi_nome)

e quindi mandiamolo a video

puts(nome_auto)

Il risultato sarà :

Auto: Honda-Jazz

Naming Convention

Come si evidenzia dalle prime righe di codice riportate notiamo che il nome della classe inizia con lettera maiuscola (Automobile).

Notiamo inoltre che il corpo del metodo viene definito dalla keyword

def


seguita dal nome del metodo e termina con

end

Una variabile preceduta da @ è una variabile di istanza.

@variabile_istanza

Per una variabile di classe avremmo avuto @@ seguite dal nome della variabile

@@variabile_di_ classe

Per una variabile globale avremmo avuto

$variabileglobale


o

$VARIABILE_GLOBALE

Il simbolo # precede il commento. Anche se all‘interno di una stringa #[espressione] viene sotituito da [espressione] come nell‘esempio sopra riportato al metodo componi_nome.

Estendiamo la classe

Creiamo una classe che estende Automobile.

class Utilitaria < Automobile
def componi_nome
super + " che utilitaria!!!!"
end
end

Quindi aggiungiamo:

automobile = Utilitaria.new("Honda","Jazz")
nome_auto=(automobile.componi_nome)
puts(nome_auto)

Il risultato sarà :

Auto: Honda--Jazz che utilitaria!!!!

Qualche riga di codice di esempio

Introduciamo la prima struttura di controllo. Il fine è di riuscire a muoverci agevolmente nelle situazioni che incontreremo a seguire.

Le strutture di controllo, unite a Iteratori e Blocchi sono "core concepts" in Ruby. Da notare che l‘utilizzo continuo del linguaggio ci porterà  sempre più ad approccio da "Rubyst" che ci allontanerà  da una modalità  classica di implementazione.

Nella classe Automobile aggiungiamo il metodo definisci_valore con il parametro livello (utilizziamo la notazione priva di parantesi).

def definisci_valore livello
@livello=""
if livello == 0
@livello="Scarso"
else
@livello="Buono"
end
end

Quindi invochiamo il metodo

livello_auto=(automobile.definisci_valore(3))
3.times{puts(livello_auto)}

L‘ouput sarà  ovviamente

Buono
Buono
Buono

Evidenziamo che avremmo potuto scrivere il contenuto del metodo come

if l == 0: @livello="Scarso"
else @livello="Buono"
end

oppure

@livello = if l == 0 then
"Scarso"
else
"Buono"
end

Provate e divertitevi!!!

Non abbiamo mai specificato in maniera esplicita un "return value". Potremmo farlo nel caso ce fosse bisogno, altrimenti sarà  restituita l‘ultima variabile valorizzata nel metodo. Ciò è molto comodo e da non dimenticare.

Passiamo ad un esempio un pò più articolato.

Facendo un salto dalle automobili al regno animale, creiamo una classe completa dei suoi attributi e dei suoi accessori pubblici.

class Animale
def initialize(nome, classe)
@nome=nome
@classe=classe
end
def nome
return @nome
end
def classe
return @classe
end
end

Avremmo potuto utilizzare una notazione più snella per gli accessori.

class Animale
def initialize(nome, classe)
@nome=nome
@classe=classe
end
attr_reader :nome,:classe
end

Questo consente di elencare velocemente tutti gli attributi ai quali si ha necessità  di accedere in lettura (attr_reader) o in scrittura (attr_writer) semplicemente riportandoli separati da virgola come sopra riportato.

Scriviamo qualche riga di codice puramente didattico. Ã? nostra intenzione leggere il contenuto di un file, scorrerlo, introdurre la classe Array, scrivere degli esempi di cicli e di operazioni sulle stringhe. Se poi avessimo intenzione di estendere o comprendere al meglio il nostro codice possiamo far riferimento alla documentazione RDoc dell‘installazione di base per avere degli spunti in merito.

Predisponiamo un file testo "filetoread" con il seguente contenuto (o con un contenuto che abbia la medesima formattazione)

Alligatore Rettile
Falco Uccello
Leone Mammifero
Mosca Insetto

Quindi creiamo il file esegui.rb con il seguente contenuto

require ‘animale‘
# Dichiariamo un Array
@animali=Array.new
# Facciamo un ciclo sugli elementi del file ‘filetoread‘
File.open("filetoread") do |elemento|
# Scorriamo ogni riga del file
elemento.each do |riga|
# Il primo elemento della riga è il nome,
# il secondo la classe animale.
# Utilizziamo le espressioni regolari al fine di
# separare le due stringhe
nome, classe = riga.chomp.split(/s* s*/)
# Istanziamo un Animale
animale = Animale.new(nome,classe)
# Aggiungiamo gli elementi all‘Array
@animali.push(animale)
# Lo facciamo di nuovo con una notazione diversa
@animali << animale
end
end
# Operiamo sull‘Array e facciamo un reverse
@animali=@animali.reverse
# Creiamo un file in cui scrivere
f = File.new("filetowrite", "w")
# Prendiamo ogni elemento Animale
# e scriviamo nome e classe nel file
@animali.each { |animale|
f.syswrite(animale.classe + " " + animale.nome + " ")
}

Lanciamo ruby ./esegui.rb.

Andiamo a vedere il contenuto del file creato "filetowrite". Dovrebbe contenere

Insetto Mosca
Insetto Mosca
Mammifero Leone
Mammifero Leone
Uccello Falco
Uccello Falco
Rettile Alligatore
Rettile Alligatore

Se analizziamo il codice scritto, supportati anche dai commenti, abbiamo introdotto una serie di espressioni e concetti non menzionati in precedenza.

Abbiamo utilizzato la keyword require che consente di importare nel file riferimenti a classi esterne, la classe Array e la sintassi @array.each { |arrayelement| ...do something on each element...}, le operazioni sulla classe String (anche ricorrendo a Regular Expression), l‘utilizzo della classe File utilizzata per leggere e scrivere nei file

Semplice... e divertente.

Vi invitiamo pertanto a scaricare l‘allegato "ruby-1.zip" dal menu in alto a sinistra.

Conclusioni

Abbiamo fatto una rapida panoramica di dove si colloca Ruby, in particolare visto da un Java Programmer. Siamo passati all‘installazione dell‘ambiente e abbiamo fatto "girare" le nostre prime righe di codice iniziando a comprendere la facilità  di utilizzo. Siamo quindi pronti per approfondire il linguaggio. Dobbiamo solo aspettare... il prossimo articolo.

Riferimenti

[1] Dave Thomas, "Programming Ruby. The Pragmatic Programmer‘s Guide", Pragmatic Bookshelf, 2004

http://www.pragmaticprogrammer.com

[2] Dave Thomas, "Agile Software Development with Rails. The Pragmatic Programmer‘s Guide", Pragmatic Bookshelf, 2005

http://www.pragmaticprogrammer.com

[3] Edward Lecky-Thompson, Heow Eide-Goodman, Steven D. Nowicki, Alec Cove, "Professional PHP5", Wrox, 2004

[4] Ruby homepage

http://www.ruby-lang.org

[5] Ruby Central... the source for Ruby

http://www.rubycentral.com/

[6] Ruby Installer

http://rubyinstaller.rubyforge.org

[7] Clarkware Consulting

http://clarkware.com/

[8] Obie Fernandez Blog

http://www.jroller.com/page/obie

[9] Jim Weirich, "10 Things Every Java Programmer Should Know About Ruby"

http://onestepback.org/articles/10thingshttp://onestepback.org/articles/10things

[10] An Interview with the Creator of Ruby

http://www.linuxdevcenter.com/pub/a/linux/2001/11/29/ruby.html

[11] Apache Struts

http://struts.apache.org/

[12] Apache Tapestry

http://tapestry.apache.org/

[13] FreeRIDE

http://freeride.rubyforge.org

Condividi

Pubblicato nel numero
114 gennaio 2007
Laureato in Scienze Statistiche e particolarmente attento alle novità che lo circondano, dal 1998 lavora nel settore dell‘IT. Prevalentemente coinvolto in progetti legati a Java, da un paio d‘anni è interessato al mondo Open Source. Dopo aver accumulato una notevole esperienza presso vari clienti e con vari ruoli (da programmatore…
Articoli nella stessa serie
  • Ruby
    II parte: approfondiamo alcuni aspetti del linguaggio Ruby
  • Ruby
    III parte: Iniziamo a percorrere i binari di Rails
  • Ruby
    IV parte: Rails... non solo Web Services
  • Ruby
    V parte: Ruby on Rails e Web 2.0
Ti potrebbe interessare anche