Strutture di Controllo
Questo capitolo esplora ulterioriormente le strutture di controllo di ruby.
case
Usiamo l'istruzione case per provare una
sequenza di condizioni . In superficie ciò appre
simile allo switch del C o di Java ma è
notevolmente più potente, come vedremo.
ruby> i=8
ruby> case i
| when 1, 2..5
| print "1..5"
| when 6..10
| print "6..10"
| end
6..10
nil
2..5 è un espressione che rappresenta un
range , un intervallo, tra 2 e 5, inclusi.
L'espressione seguente verifica se il valore
dii ricade in quell'intervallo:
(2..5) === i
case internamente usa l'operatore di
relazione === per verifocare molte condizioni in
una sola volta . Nel mantenere la natura orientata agli
oggetti di ruby, === viene interpretato in
amniera appropriata per l'oggetto apparso nella
condizione when. Ad esempio, il codice seguente
verifica l'uguaglianza con una stringa equality nel primo
when, e la corrispondenza con un espressione
regolare nel secondo when.
ruby> case 'abcdef'
| when 'aaa', 'bbb'
| print "aaa or bbb"
| when /def/
| print "include /def/"
| end
include /def/
nil
while
Ruby fornisce maniere convenienti per costruitr i cicli, anche se scoprirete nel prossimo capitolo che l'uso degli iteratori renderà spesso inutile scrivere cicli esplicitamente.
Un while è un if ripetuto,
lo abbiamo usato nel nostro giochino di sull'indovinare
le parole e nei programmi sulle espressioni regolari (vedere
ilcapitolo precedente); in quei contesi esso aveva la forma
di while condizione ... end intorno ad
un blocco di codice che doveva essere ripetuto fino a che
condizione fosse rimasta vera. Ma while
ed if possono essere applicati facilmente anche
ad istruzioni singole:
ruby> i = 0 0ruby> print "E' zero." if i==0It's zero. nilruby> print "E' negativo." if i<0 nilruby> print "#{i+=1}" while i<3123 nil
Alcune volte correte negare una condizione. Un
unless è un if negatom ed un
until è un while negato.
Lasciamo a voi il compito di sperimentare anche con questi.
Ci sono quattro modi per interrompere lìavanzamento di
un ciclo dall'interno. Per primo, break
rappresenta, come in C, l'uscita definitiva dal ciclo.
Secondo, next salta all'inizio
dell'iterazione seguente (corrispondente al
continue del C). Terzo, ruby ha
redo, che riavvia l'iterazione corrente. Il
codice C seguente illustra il significato di
break, next, e redo:
while (condizione) {
label_redo:
goto label_next; /* "next" di ruby */
goto label_break; /* "break" di ruby */
goto label_redo; /* "redo" di ruby */
...
...
label_next:
}
label_break:
...
Il quarto modo per uscire da un ciclo è con
l'istruzione return. L'analisi di un
return causa l'uscita non solo da un loop ma
dal meytodo che contiene quel loop. Se viene passato un
argomenti, esso verra restituito dalla chiamata al metodo ,
altrimenti verrà restituito nil .
for
I programmatori C ora si staranno chiedendo come fare un
ciclo "for" in ruby. Il for di ruby
è un po' più interessante di quello che ci
si potrebbe aspettare. Il ciclo qui sotto viene eseguito una
volta per ogni elemento nella collezione :
for elt in collezione ... end
La collezione può essere un intervallo di valori (è di questo che parla la gente in genere , riferendosi ad un ciclo for ):
ruby> for num in (4..6)
| print num,""
| end
4
5
6
4..6
Potrebbe anche essere un altro tipo di collezione, come un array:
ruby> for elt in [100,-9.6,"pickle"]
| print "#{elt} (#{elt.type})"
| end
100 (Fixnum)
-9.6 (Float)
pickle (String)
[100, -9.6, "pickle"]
Ma stiamo andando troppo avanti. for in
realtà è un altro modo per scrivere
each, che dunque, è il mnostro primo
esempio di iteratore. Le seguenti due forme sono equivalenti:
# se siete abituati a C o Java, potreste preferire questo.
for i in collezione
...
end
# un programmatore Smalltalk preferirebbe questo .
collection.each {|i|
...
}
Gli iteratori possono speso sostituire i cicli convenzionali , ed una volta che vi sarete abituati ad essi, in generale sarà più semplice averci a che fare . Dunque andioamo avanti e impariamo qualcos'altro su di essi.