Abbiamo parlato della parola chiave retry
mentre discutevamo di ritentare dopo le eccezioni. La sua controparte poco conosciuta redo
funziona in modo simile, ma riesegue le iterazioni del ciclo invece di interi blocchi.
La parola chiave redo
Come abbiamo imparato nel precedente articolo di Academy, retry
permette di riprovare un pezzo di codice in un blocco:
1 2 3 4 5 6 |
begin puts "Iteration" raise rescue retry end |
Questo esempio stampa la parola “Iterazione” sulla console prima di sollevare un’eccezione. Viene eseguito il blocco di salvataggio, che chiama retry
e fa ripartire il blocco dall’inizio. Il risultato è che il nostro programma stampa all’infinito Iteration
. La parola chiave redo
permette di ottenere un effetto simile quando si usano i loop. Questo è utile in situazioni in cui è necessario riprovare mentre si itera, per esempio.
1 2 3 4 |
10.times do |i| puts "Iteration #{i}" redo if i > 2 end |
Questo stampa:
1 2 3 4 5 6 7 8 |
$ ruby redo.rb Iteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 3 Iteration 3 ... |
Nota come il numero di iterazioni rimane lo stesso? L’esecuzione torna indietro all’inizio del ciclo. Questa variante del codice usando retry
stamperà esattamente lo stesso output:
1 2 3 4 5 6 7 8 |
10.times do |i| begin puts "Iteration #{i}" raise if i > 2 rescue retry end end |
Puoi usare redo
per implementare il retrying in un ciclo. Nel prossimo esempio abbiamo una coda di lavori. Essi restituiscono :success
o :failure
. Continuiamo a ripetere la stessa iterazione del ciclo finché il lavoro non ha successo.
1 2 3 |
.each do |job| redo unless job.call == :success end |
Ruby 1.8
Il comportamento di retry
e redo
è cambiato tra Ruby 1.8 e 1.9. Riavviavano l’iterazione del ciclo, ma entrambi in modo diverso. Dalla 1.9, retry
funziona solo con un blocco begin
/rescue
e redo
funziona solo all’interno dei loop.
La parola chiave next
Se vuoi passare alla prossima iterazione del ciclo, invece di tornare indietro all’inizio di quella corrente, puoi usare next
.
1 2 3 4 5 |
10.times do |i| puts "Iteration #{i}" next if i > 2 puts "Iteration done" end |
Questo stampa:
1 2 3 4 5 6 7 8 9 10 |
$ ruby next.rb Iteration 0 Iteration done Iteration 1 Iteration done Iteration 2 Iteration done Iteration 3 Iteration 4 ... |
Vedi come il contatore delle iterazioni continua ad aumentare? Nella maggior parte dei casi usare next
è quello che vuoi. Guardate redo
se avete bisogno di un ciclo che venga eseguito un numero esatto di volte o se avete bisogno di una gestione degli errori quando iterate su un array.
Speriamo che abbiate imparato qualcosa di nuovo sul rifare le iterazioni nei cicli e ci piacerebbe sapere cosa ne pensate di questo articolo (o qualsiasi altro della serie AppSignal Academy). Non esitate a farci sapere cosa ne pensate, o se avete qualche argomento di Ruby che vorreste approfondire.