Programming Ruby

The Pragmatic Programmer's Guide

Precedente < Indice ^
Prossimo >

Ruby.new


Quando abbiamo scritto all'inizio questo libro, avevamo un grande piano (eravamo giovani allora!). Volevamo documentare il linguaggio dall' inizio alla fine, iniziando dalle classi e dagli oggetti, per finire con i dettagli sintattici. Sembrava una buona idea a quel tempo. Dopo tutto, in Ruby quasi tutto è un oggetto, così avrebbe avuto senso parlare degli oggetti come prima cosa.

O almeno così pensavamo.

Sfortunatamente, si è dimostrato difficile descrivere un linguaggio in questo modo. Se voi non avete compreso le stringhe, le affermazioni if, gli assegnamenti, ed altri dettagli, è difficile scrivere esempi di classi. Da un capo all'altro della nostra descrizione, abbiamo avuto cura affrontando dettagli di basso livello la necessità di dimostrarli con esempi di codice che avessero senso.

Così, abbiamo generato un nuovo grande piano (non ci chiamiamo pragmatici per nulla). Avremo descritto Ruby partendo comunque da in cima. Ma per prima cosa avremo fatto questo, avremo aggiunto un piccolo capitolo che avrebbe descritto tutte le comuni caratteristiche usate negli esempi, insieme al speciale vocabolario usato in Ruby, una specie di minitutorial per lanciarci all'interno del libro.

Ruby è un linguaggio Object-Oriented

Permettetemi di dirlo nuovamente. Ruby è un vero linguaggio orientato agli oggetti. Ogni cosa che manipoli è un oggetto, e il risultato di queste manipolazioni sono loro stessi degli oggetti. Comunque, molti linguaggi hanno la stessa pretesa, e spesso hanno anche una differente interpretazione di che cosa significhi ''orientato agli oggetti' e un differente terminologia per i concetti che impiegano.

Così, prima di innoltrarci troppo nei dettagli, guarderemo brevemente i termini e le notazioni che noi useremo.

Quando scrivete un codice object oriented (da questo punto useremo il termine originale e non più la traduzione), cercherete di migrare modelli concettuali dal mondo reale verso il vostro codice. Tipicamente durante questo processo di creazione dei modelli , scoprirete categorie di cose che si renderanno necessarie trasmigrare nel codice. In un jukebox, il concetto di una ``canzone" potrebbe essere una categoria. In Ruby, dovreste definire una classe per rappresentare ognuna di queste categorie. Una classe è una combinazione di stati (per esempio, il nome della canzone) e di metodi che usa questo stato (peraltro un metodo per suonare la canzone).

Una volta che avrete queste classi, vorrete normalmente creare un numero di instanze per ogni classe. Per il sistema jukebox inclusa una classe, definita Song, dovreste avere instanze separate per i più famosi successi, ad esempio ``Martedi Ruby", ``Sviluppato in Python", ``Stringhe in Perl",``Smalltalk" e così via. La parola object è usato intercambiabilmente con instanze di classe (ad essere tipi indolenti, probabilmente useremo la parola``object" più frequentemente)

In Ruby, questi oggetti sono creati chiamando un costruttore, un metodo speciale associato ad una classe. Il costruttore standard è new

song1 = Song.new("Ruby Tuesday")
song2 = Song.new("Enveloped in Python")
# e così avanti

Queste instanze sono entrambe derivate dalla stessa classe, ma hanno una caratteristica unica. Primo, ogni oggetto ha un unico identificatore d' oggetto(abbreviato con object id. Secondo, potrete definire le variabili istanza, variabili con valori che sono unici per ogni istanza. Queste variabili istanza mantengono unito lo stato dell' oggetto. Ognuna delle nostre canzoni, per esempio, avrà una variabile istanza che manterrà il titolo della canzone.

All'interno di ogni classe, si può definire un metodo istanza. Ogni metodo è un grosso pezzo di funzionalità che potrebbe essere chiamato dall'interno della classe e (dipende dalle restrizioni di accesso) dall'esterno. Questi metodi istanza, una volta avviati, hanno accesso alle variabili istanza dell' oggetto, e da quì allo stato dell' oggetto.

I metodi sono invocati inviando un messaggio ad un oggetto. Il messaggio contiene il nome del metodo, insieme con tutti i parametri di cui l' oggetto può evere bisogno. [Questa idea di esprimere i metodi chiamata nella forma dei messaggi deriva dal Smaltalk]

Questi affari di metodi e messaggi devono suonare complicati, ma in pratica è molto semplice. Osserviamo alcuni metodi di chiamata. (Ricordate che le frecce nel codice dell' esempio mostrano i valori di ritorno delle corrispondenti espressioni).

"gin joint".length » 9
"Rick".index("c") » 2
-1942.abs » 1942
sam.play(aSong) » "duh dum, da dum de dum ..."

Quì la cosa antecedente il periodo è chiamata receiver, e il nome che segue il periodo è il metodo da essere invocato. Il primo esempio interroga una stringa della sua lunghezza e il secondo interroga una stringa differente per scoprire l' indice della lettera ``c". La terza linea ha un numero calcolato in valore assoluto. In ultimo chiediamo a Sam di suonare una canzone.

La differenza tra Ruby e la maggior parte degli altri linguaggi si azzere in questo punto. In Java, dovendo trovare il valore assoluto di alcuni numeri, si rende necessario chiamare una funzione e passargli il numero. Potreste scrivere:

number = Math.abs(number)     // codice in Java 

In Ruby, l' abilità di determinare un valore assoluto è scritto nei numeri, perchè si prendono cura dei dettagli internamente. Semplicemente invierete il messaggio abs ad un oggetto numero, ed esso farà il lavoro.

number = number.abs

Lo stesso si applica a tutti gli Oggetti in Ruby: nel linguaggio C dovresti scrivere strlen(name), mentre in Ruby diverrà name.lenght, e così avanti. Questa è una parte del significato dell' affermazione che Ruby è un vero linguaggio OO.

Alcuni Concetti di base di Ruby

A poche persone piace leggere troppe noiose regole sintattiche quando stanno facendo la conoscenza di un nuovo linguaggio. Per questo vi andremo ad ingannare. In questa sezione andremo a scoprire alcune delle cose più importanti, la sostanza di quello che dovrete sapere se vorrete scrivere Programmi in Ruby. Più tardi, nel capitolo 18, che incomincia a pagina 201, entreremo nei più truculenti dettagli.

Iniziamo con un semplice programma in Ruby. Scriveremo un metodo che ritornerà una stringa, aggiungendo a questa stringa un nome di persona. Di conseguenza invocheremo il metodo un paio di volte.

def sayGoodnight(name)
  result = "Goodnight, " + name
  return result
end

puts sayGoodnight("John-Boy")
puts sayGoodnight("Mary-Ellen")

Come prima cosa, alcune osservazioni di carattere generale. La sintattica di Ruby è chiara. Non hai bisogno di punti e virgole alla fine di affermazioni così lunghe da mettere ogni affermazione su righe separate. I commenti in Ruby incominciano con un carattere # e valgono per tutta la riga. Il layout del codice ti aiuta, maiuscole e minuscole non sono importanti.

I metodi si identificano con la parola def, seguita dal nome del metodo (in questo caso, ``sayGoodnight'') e i parametri del metodo tra parentesi. Ruby non utilizza graffe per delimitare il corpo dell' espressione composta da più righe. Invece, si utilizza più semplicemente la parola end. Il corpo del metodo è piuttosto semplice. La prima linea concatena la stringa letterale ``Goodnight,[visible space]'' al parametro name ed assegna il risultato alla variabile locale result. La linea seguente restituisce questo valore al chiamante. Nota che non dobbiamo dichiarare la variabile result; nasce quando gli viene assegnato un valore.

Avendo definito il metodo, lo chiamiamo due volte. In entrambi i casi, passiamo il risultato a puts, che semplicemente invia in output i suoi argomenti seguiti da una nuova linea.

Goodnight, John-Boy
Goodnight, Mary-Ellen

La linea``puts sayGoodnight("John-Boy")'' contiene due chiamate a metodi, una a sayGoodnight e l' altra a puts. Perchè una ha tra parentesi l' argomento, mentre l' altra no? In questo caso si tratta solamente di questione di gusto. Le righe seguenti sono equivalenti.

puts sayGoodnight "John-Boy"
puts sayGoodnight("John-Boy")
puts(sayGoodnight "John-Boy")
puts(sayGoodnight("John-Boy"))

Comunque la vita non è sempre così semplice e le regole precedenti posso rendere difficile sapere quali argomenti si accoppiano a quale invocazione di metodo, così raccomandiamo di usare le parentesi in tutti i casi, anche i più semplici.

Questo esempio mostra nuovamente alcuni oggetti stringa. Esistono molti modi per creare un oggetto stringa, ma probabilmente il più comune è di usare le stringhe letterali: sequenze di caratteri tra singole o doppi apici (``'"). La differenza tra le due consiste nella quantita' di processi che Ruby esegue sulla stringa durante la formulazione letterale. Nel caso di un solo apice, Ruby fà molto presto. Con alcune eccezioni, ciò che digiti nella stringa diventa il valore della stringa.

Nel caso del doppio apice, Ruby fa' più lavoro. Dapprima, cerca eventuali sostituzioni ---sequenze che incominciano con una barra rovesciata--- e le rimpiazza con i valori binari. Il più comune di questi è ``\n'', che è rimpiazzato con un valore di nuova linea. Quando una stringa contenente una nuova linea è mandata in output, il ``\n'', forza ed interrompe la riga.

puts "And Goodnight,\nGrandma"

produce:

And Goodnight,
Grandma

La seconda cosa che Ruby fà con le stringhe contenenti i doppi apici è l' interpolazione dell' espressione. All'interno della stringa, la sequenza #{expression} è sostituita dal valore expression. Possiamo usare questa caratteristica per riscrivere il nostro precedente metodo.

def sayGoodnight(name)
  result = "Goodnight, #{name}"
  return result
end

Quando Ruby costruisce questo oggetto stringa, guarda il valore corrente di name e lo sostituisce all'interno della stringa. ... Come scorciatoia, non avete bisogno di sostituire le graffe quando un espressione è semplicemente una variabile globale, istanza o di classe. Per maggiori informazioni sulle stringhe, quali le altre tipologie standard di Ruby, vai al capitolo 5, che incomincia a pagina 49.

Alla fine possiamo semplificare questo metodo ulteriormente. Il valore ritornato da un metodo di Ruby è il valore dell' ultima espressione valutata, così possiamo disfarci completamente della dichiarazione return.

def sayGoodnight(name)
  "Goodnight, #{name}"
end

Abbiamo promesso che la sezione sarebbe stata breve. Abbiamo solamente ancora un punto da esaminare: i nomi in Ruby. Per brevità useremo alcuni termini (ad esempio una variabile classe) che non andremo a definire quì. Comunque, parlando ora delle regole , sarete in anticipo sul gioco quando arriveremo a discutere delle variabili istanza e simili più avanti.

Ruby utilizza una convenzione per aiutarlo a distinguere l' uso del nome: il primo carattere del nome indica come il nome è usato. Le variabili locali, i parametri dei metodi, ed i nomi dei metodi devono incominciare con una lettera minuscola o con un underscore (_). Le variabili globali sono prefissate da un segno dollaro ($), mentre le variabili istanza incominciano con un ``at" (@). Le variabili classe iniziano con una doppia ``at" (@@). Per ultimo, i nomi delle classi e le costanti, dovrebbero iniziare con una lettera maiuscola. Esempi dei differenti nomi sono mostrati nella tavola 2.1 a pagina 10.

Seguendo questo capitolo iniziale, un nome può essere una combinazione di lettere, segni, sottolineature (con la condizione che il carattere che segue un segno @ non sia una cifra).

Esempi di nomi variabile e classe
Variabili Costanti e
Locali Globali Instanze Classi Nomi di Classi
name $debug @name @@total PI
fishAndChips $CUSTOMER @point_1 @@symtab FeetPerMile
x_axis $_ @X @@N String
thx1138 $plan9 @_ @@x_pos MyClass
_26 $Global @plan9 @@SINGLE Jazz_Song

Arrays e Hashes

Gli array e gli hash di Ruby sono una collezione di indici. Entrambi abbondano di collezioni di oggetti, accessibili usando una chiave. Con gli Array, la chiave è un intero, mentre per gli Hash qualsiasi oggetto è una chiave. Entrambi gli Array e gli Hash, crescono a seconda del bisogno per inglobare nuovi elementi. Risulta più efficiente accedere agli elementi di un Array, mentre gli Hash possono vantare una maggiore flessibilità. Qualunque Array o Hash può aggiungere oggetti di differenti tipi; potreste avere un Array contenente un intero, una stringa ed un numero a virgola (decimale), come vedremo tra un minuto.

Potreste creare ed inizializzare un nuovo Array con un Array letterale --- un insieme di elementi tra parentesi quadre. Dato un oggetto Array, potrete accedere agli elementi che lo compongono grazie ad un indice tra le parentesi quadre, come l' esempio mostra.

a = [ 1, 'cat', 3.14 ]   # array con tre elementi
# accede il primo elemento
a[0] » 1
# setta il terzo elemento
a[2] = nil
# dump out the array
a » [1, "cat", nil]

Potrete creare un Array vuoto anche usando un array letterale senza elementi oppure utilizzando il costruttore di oggetti Array, Array::new.

empty1 = []
empty2 = Array.new

Talvolta creando Array di parole ci si può trovare in difficoltà con tutti gli apici e le virgole. Fortunatamente, esiste una scorciatoia: %w fà esattamente ciò di cui abbiamo bisogno.

a = %w{ ant bee cat dog elk }
a[0] » "ant"
a[3] » "dog"

Gli Hash di Ruby sono simili agli Array. Un Hash letterale usa le parentesi graffe al posto delle quadre. Per esattezza deve fornire due oggetti per ogni inserimento: una per la chiave e l' altra per il valore.

Per esempio, potreste voler tenere traccia degli strumenti musicali e del genere a cui appartengono. Potrete fare ciò con un Hash.

instSection = {
  'cello'     => 'string',
  'clarinet'  => 'woodwind',
  'drum'      => 'percussion',
  'oboe'      => 'woodwind',
  'trumpet'   => 'brass',
  'violin'    => 'string'
}

Gli Hash utilizzano le stesse parentesi quadre degli array.

instSection['oboe'] » "woodwind"
instSection['cello'] » "string"
instSection['bassoon'] » nil

Come evidenziato dall'ultimo esempio, un Hash ritorna di default il valore nil quando è indicizzato da una chiave che non è compresa. Normalmente può tornare utile, poichè nil significa falso quando usato in un' espressione condizionale. Talvolta potreste voler cambiare questo valore. Per esempio, se state utilizzando un Hash per contare il numero di volte di un occorrenza, risulta necessario avere il valore di partenza a zero. Questo è fatto facilmente specificando un determinato valore quando create un nuovo Hash vuoto.

histogram = Hash.new(0)
histogram['key1'] » 0
histogram['key1'] = histogram['key1'] + 1
histogram['key1'] » 1

Gli oggetti Array e Hash possono vantare numerosi metodi utili: osservate la discussione che inizia a pagina 35, e per maggiori dettagli le sezioni di riferimento che iniziano alle pagine 282 e 321.

Le strutture di controllo

Ruby dispone di tutte le strutture di controllo, come if e while. I programmatori in Java, C e Perl dovrebbero afferrare l' assenza di parentesi graffe intorno al corpo delle espressioni. Al loro posto, Ruby utilizza la parola end per determinare la fine del corpo.

if count > 10
  puts "Try again"
elsif tries == 3
  puts "You lose"
else
  puts "Enter a number"
end

Similmente l' espressione while termina con un end.

while weight < 100 and numPallets <= 30
  pallet = nextPallet()
  weight += pallet.weight
  numPallets += 1
end

I modificatori d' istruzione di Ruby sono una utile scorciatoia se il corpo di un espressione if o di un while è solamente una singola espressione. Si potrà semplicemente scrivere l' espressione, seguita da if o while e la condizione. Per esempio, ecco una semplice espressione if.

if radiation > 3000
  puts "Danger, Will Robinson"
end

Eccolo ripresentato, riscritto utilizzando modificatori d'istruzione

puts "Danger, Will Robinson" if radiation > 3000

Similmente, un espressione ciclica (loop) di while come la seguente

while square < 1000
   square = square*square
end

diviene più concisa.

square = square*square  while square < 1000

Questi modificatori d'istruzioni dovrebbero essere famigliari ai programmatori del Perl.

Espressioni Regolari

La maggioranza dei tipi incorporati in Ruby saranno familiari ai programmatori. La maggior parte dei linguaggi dispongono di stringhe, numeri interi, con la virgola, array e molto altro. Comunque, finchè Ruby si è sviluppato, il supporto alle espressioni regolari è stato inserito all'interno dei così chiamati linguaggi di scripting, tipo il Perl, Python ed altri. E' un peccato: espressioni regolari, benchè criptiche, sono un potente strumento per lavorare con il testo. Esistono interi libri che trattano delle espressioni regolari (per esempio, Mastering Regular Expressions ), così non ci dilungheremo su tutto in una così breve sezione. Invece, osserveremo alcuni esempi di espressioni regolari all'opera. Troverete una copertura completa delle espressioni regolari a partire da pagina 58.

Un' espressione regolare è semplicemente un modo di specificare un pattern (insieme) di caratteri uniti in una stringa. In Ruby, potrete creare un espressione regolare scrivendo un pattern di caratteri tra barre oblique (slash) (/pattern/). E, Ruby essendo Ruby, poichè e' espressioni regolari sono oggetti saranno quindi manipolabili.

Per esempio, potreste scrivere un pattern, che uniformi una stringa contenente il testo ``Perl" o il test ``Python" usando la seguente espressione regolare

/Perl|Python/

Le barre oblique delimitano il pattern, che consiste in due cose che stiamo uniformando, separate da un carattere pipe (``|''). Si posso usare le parentesi all'interno del pattern, esattamente come in una espressione aritmetica, così si sarebbe potuto scrivere in questo modo:

/P(erl|ython)/

Si possono anche specificare delle ripetizioni all'interno dei pattern. /ab+c/ indica una stringa contenente una ``a" seguita da una o più ``b" e da una ``c". Cambiate il più con un asterisco, e/ab*c/ creerete una espressione regolare che identifica una ``a", nessuna o più ``b" ed una ``c".

Si possono anche cercare un carattere all'interno di una stringa. Alcuni comuni esempi sono classe di caratteri come ``\s'', che indica uno spazio vuoto (spazio, tabulazione, nuova linea e così avanti), ``\d'', che corrisponde a qualsiasi cifra, ``\w'', che corrisponde a qualsiasi carattere che deve apparire in un certa parola. Il punto ``.'' indica qualsiasi carattere.

Mettiamo tutto insieme per produrre qualche utile espressione regolare.

/\d\d:\d\d:\d\d/     # un orario come 12:34:56
/Perl.*Python/       # Perl, zero o più caratteri, poi Python
/Perl\s+Python/      # Perl, uno o più spazi, poi Python
/Ruby (Perl|Python)/ # Ruby, uno spazio, e infine Perl o Python

Una volta creato un modello, risulta una follia non usarlo. L' operatore di corrispondenza ``=~'' confronta una stringa con un' espressione regolare. Se il modello è trovato nella stringa, ``=~'' ritorna la sua posizione di partenza, altrimenti il valore di ritorno sarà nil. Questo significa che potrete utilizzare un' espressione regolare alla pari di una condizione if o un' espressione while. Per esempio, il seguente frammento di codice scrive un messaggio se una stringa contiene il testo 'Perl' oppure 'Python'.

if line =~ /Perl|Python/
  puts "Scripting language mentioned: #{line}"
end

La parte di stringa confrontata da un' espressione regolare potrà essere rimpiazzata con un testo differente usando un metodo di sostituzione di Ruby..

line.sub(/Perl/, 'Ruby')    # riposiziona prima 'Perl' con 'Ruby'
line.gsub(/Python/, 'Ruby') # riposiziona ogni 'Python' con 'Ruby'

Bè avremo molto di che parlare sulle espressioni regolari all'interno del libro.

Blocchi e Iteratori

Questa sezione descrive brevemente uno dei punti di forza di Ruby. Osserviamo i blocchi di codice: pezzi di codice che potete richiamare con le invocazioni dei metodi, come se fossero dei parametri. Questa è una caratteristica incredibilmente potente. Si possono utilizzare i blocchi di codice per effettuare delle implementazioni di chiamata ( ma sicuramente più semplici delle classi anonime interne del Java), passare internamente blocchi di codice (ma più flessibili dei puntatori di funzione del C) per effettuare le iterazioni.

I blocchi di codice sono pezzi di codice compresi tra parentesi graffe oppure tra do...end.

{ puts "Hello" }       # questo è un blocco

do                     #
  club.enroll(person)  # and so is this
  person.socialize     #
end                    #

Una volta creato un blocco, si possono associare ad una chiamata di un metodo. Questo metodo può poi invocare il blocco una o più volte usando l' espressione di Ruby yield. Il seguente esempio mostra questa caratteristica in azione. Definiamo un metodo che chiama yield due volte. Lo chiamiamolo, inserendo il blocco sulla stessa linea, dopo la chiamata (e dopo tutti gli argomenti al metodo). [Ad alcune persone piace pensare all'associazione di un blocco con un metodo cose se fosse una specie di parametro da passare. Certamente lavora su un livello, ma non rappresenta completamente l' intera storia. Sarebbe meglio se consideraste il blocco di codice ed il metodo come delle coroutine, che trasferiscono il controllo avanti ed indietro tra di loro.]

def callBlock
  yield
  yield
end

callBlock { puts "In the block" }

produce:

In the block
In the block

Osservate come il codice nel blocco (puts "In the block") sia eseguito due volte, una per ogni chiamata di yield.

Potete stabilire i parametri da passare a yield: questi saranno passati al blocco. All'interno del blocco, potrete indicare i nomi degli argomenti per ricevere questi parametri tra barre verticali (``|'').

  def callBlock
    yield , 
  end

  callBlock { |, | ... }

I blocchi di codice sono usati ovunque nelle librerie di Ruby per implementare le iterazioni: i metodi che ritornano elementi successivi da alcuni tipi di collezioni, cose se fossero array.

a = %w( ant bee cat dog elk )    # crea un array
a.each { |animal| puts animal }  # lo itera con il suo contenuto

produce

ant
bee
cat
dog
elk

Osserviamo come potremo implementare l' Array iteratore della classe each che abbiamo utilizzato nel precedente esempio. L' iteratore each esegue un loop attraverso ogni elemento nell'array, richiamando yield per ognuno. Espresso in codice, potrebbe assomigliare a:

# all'interno di una classe Array...
def each
  for each element
    yield(element)
  end
end

Potrete quindi creare un' iterazione sugli elementi di un array richiamando il suo metodo each e fornendogli un blocco. Questo blocco dovrà essere chiamato per ogni elemento a turno.

[ 'cat', 'dog', 'horse' ].each do |animal|
  print animal, " -- "
end

produce:

cat -- dog -- horse --

In modo simile, molte costruzioni a loop che sono create nei linguaggi tipo il C e Java, in Ruby sono più semplici delle chiamate al metodo.

5.times {  print "*" }
3.upto(6) {|i|  print i }
('a'..'e').each {|char| print char }

produce:

*****3456abcde

Quì chiediamo al numero 5 di chiamare un blocco cinque volte, poi chiediamo al numero 3 di chiamare un blocco, passargli successivi valori fino a che non raggiunge il 6. Alla fine, il campo di caratteri da ``a" fino a ``e" è invocato da un blocco usando il metodo each.

Reading and 'Riting

Ruby dispone di una vasta libreria di I/O. Comunque, nella maggioranza degli esempi del libro rimarremo legati a pochi semplici metodi. Finora abbiamo incontrato due metodi che gestiscono l' output. puts scrive ognuno dei suoi argomenti aggiungendo una linea tra ognuno. print invece scrive i suoi argomenti senza una nuova linea. Entrambi possono essere usati per scrivere qualsiasi oggetto di I/O, ma di default scrivono in consolle.

Un altro metodo che useremo molto è printf, che stampa i suoi argomenti sotto il controllo di una stringa formattata (esattamente come il printf del C o del Perl).

printf "Number: %5.2f, String: %s", 1.23, "hello"

produce:

Number:  1.23, String: hello

In questo esempio, il formato della stringa "Number: %5.2f, String: %s" comunica a printf di sostituire un numero con virgola (floating point), ammettendo cinque caratteri in totale, di cui due dopo la virgola) e una stringa.

Ci sono molti modi di leggere l'input all'interno del vostro programma. Probabilmente il più tradizionale è di usare la routine gets, che ritorna la prossima riga dal flusso del standard input del vostro programma.

line = gets
print line

La routine gets ha un effetto collaterale: come viene letta la linea in arrivo, la salva nella variabile globale $_. Questa variabile è speciale, e per questo è usata come argomento di default in molte circostanze. Se si chiama print senza argomenti, viene stampato il valore di $_. Se scrivete un espressione con if o while con una espressione regolare come condizione, quella espressione è confrontata con $_. Finchè sarà visto da alcuni puristi come un barbarismo, queste abbreviazioni potranno aiutarvi a scrivere alcuni concisi programmi. Per esempio il seguente programma stampa tutte le linee del flusso di input che contengono la parola ``Ruby".

while gets           # assegna la linea a $_
  if /Ruby/          # la confronta con $_
    print            # stampa $_
  end
end

Il'modo Ruby' per scrivere questo utilizzerà un iteratore.

ARGF.each { |line|  print line  if line =~ /Ruby/ }

Questo utilizza l' oggetto predefinito ARGF, che rappresenta il flusso di input che potrà essere letto dal programma.

Sempre più in Avanti ed in alto

Questo è tutto. Abbiamo terminato il nostro rapido e leggero tour intorno ad alcune delle caratteristiche di base di Ruby. Abbiamo dato una vista agli oggetti, i metodi, le stringhe, i contenitori, e le espressioni regolari, osservato alcune semplici strutture di controllo, e guardato alcuni eleganti iterazioni. Speranzosi, questo capitolo ha fornito sufficiente munizioni per essere in grado di attaccare il resto di questo libro.

Tempo per muoversi in avanti e sempre più in alto. Prossimamente osserveremo le classi e gli oggetti, cose che sono allo stesso tempo il più elevato costrutto in Ruby ed essenziale mattone dell' intero linguaggio.


Precedente < Inizio ^
Prossimo >

Estratto dal libro "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright © 2000 Addison Wesley Longman, Inc. Released under the terms of the Open Publication License V1.0.
This reference is available for download.