Strutture di Controllo
Questo capitolo esplora ulterioriormente le strutture dicontrollo di ruby.
case
Usiamo l'istruzione case
per provare unasequenza di condizioni . In superficie ciò appresimile allo switch
del C o di Java ma ènotevolmente più potente, come vedremo.
ruby> i=8ruby> case i | when 1, 2..5 | print "1..5" | when 6..10 | print "6..10" | end6..10 nil
2..5
è un espressione che rappresenta unrange , un intervallo, tra 2 e 5, inclusi.L'espressione seguente verifica se il valoredii
ricade in quell'intervallo:
(2..5) === i
case
internamente usa l'operatore direlazione ===
per verifocare molte condizioni inuna sola volta . Nel mantenere la natura orientata aglioggetti di ruby, ===
viene interpretato inamniera appropriata per l'oggetto apparso nellacondizione when
. Ad esempio, il codice seguenteverifica l'uguaglianza con una stringa equality nel primowhen
, e la corrispondenza con un espressioneregolare nel secondo when
.
ruby> case 'abcdef' | when 'aaa', 'bbb' | print "aaa or bbb" | when /def/ | print "include /def/" | endinclude /def/ nilwhile
Ruby fornisce maniere convenientiper costruitr i cicli, anche se scoprirete nel prossimocapitolo che l'uso degli iteratorirenderà spesso inutile scrivere cicli esplicitamente.
Un while
è un if
ripetuto,lo abbiamo usato nel nostro giochino di sull'indovinarele parole e nei programmi sulle espressioni regolari (vedereilcapitolo precedente); in quei contesi esso aveva la formadi while condizione ... end
intorno adun blocco di codice che doveva essere ripetuto fino a checondizione fosse rimasta vera. Ma while
ed if
possono essere applicati facilmente anchead 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. Ununless
è un if
negatom ed ununtil
è un while
negato.Lasciamo a voi il compito di sperimentare anche con questi.
Ci sono quattro modi per interrompere lìavanzamento diun ciclo dall'interno. Per primo, break
rappresenta, come in C, l'uscita definitiva dal ciclo.Secondo, next
salta all'iniziodell'iterazione seguente (corrispondente alcontinue
del C). Terzo, ruby haredo
, che riavvia l'iterazione corrente. Ilcodice C seguente illustra il significato dibreak
, 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 è conl'istruzione return
. L'analisi di unreturn
causa l'uscita non solo da un loop madal meytodo che contiene quel loop. Se viene passato unargomenti, esso verra restituito dalla chiamata al metodo ,altrimenti verrà restituito nil
.
for
I programmatori C ora si staranno chiedendo come fare unciclo "for" in ruby. Il for
di rubyè un po' più interessante di quello che cisi potrebbe aspettare. Il ciclo qui sotto viene eseguito unavolta 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,"" | end456 4..6
Potrebbe anche essere un altro tipo di collezione, come unarray:
ruby> for elt in [100,-9.6,"pickle"] | print "#{elt} (#{elt.type})" | end100 (Fixnum)-9.6 (Float)pickle (String) [100, -9.6, "pickle"]
Ma stiamo andando troppo avanti. for
inrealtà è un altro modo per scrivereeach
, che dunque, è il mnostro primoesempio 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 generalesarà più semplice averci a che fare . Dunqueandioamo avanti e impariamo qualcos'altro su di essi.