Am vorbit despre cuvântul cheie retry
când am discutat despre reluarea încercărilor după excepții. Omologul său puțin cunoscut redo
funcționează în mod similar, dar reia iterațiile buclei în loc de blocuri întregi.
Cuvântul cheie redo
După cum am învățat în articolul anterior al Academiei, retry
vă permite să încercați din nou o bucată de cod într-un bloc:
1 2 3 4 5 6 |
begin puts "Iteration" raise rescue retry end |
Acest exemplu tipărește cuvântul „Iteration” pe consolă înainte de a ridica o excepție. Se execută blocul de salvare, care apelează retry
și pornește blocul din nou de la început. Acest lucru are ca rezultat faptul că programul nostru imprimă la nesfârșit Iteration
. Cuvântul cheie redo
vă permite să obțineți un efect similar atunci când folosiți bucle. Acest lucru este util în situațiile în care trebuie să încercați din nou în timp ce iterați, de exemplu.
1 2 3 4 |
10.times do |i| puts "Iteration #{i}" redo if i > 2 end |
Acest lucru se va imprima:
1 2 3 4 5 6 7 8 |
$ ruby redo.rb Iteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 3 Iteration 3 ... |
Observați cum numărul de iterații rămâne același? Se va face un pas înapoi în execuție până la începutul buclei. Această variantă a codului care utilizează retry
va imprima exact aceeași ieșire:
1 2 3 4 5 6 7 8 |
10.times do |i| begin puts "Iteration #{i}" raise if i > 2 rescue retry end end |
Puteți utiliza redo
pentru a implementa reluarea încercării într-o buclă. În exemplul următor avem o coadă de lucrări. Acestea returnează fie :success
, fie :failure
. Continuăm să reluăm aceeași iterație a buclei până când sarcina reușește.
1 2 3 |
.each do |job| redo unless job.call == :success end |
Ruby 1.8
Comportamentul lui retry
și redo
s-a schimbat între Ruby 1.8 și 1.9. Ele obișnuiau să repornească iterația buclei, dar ambele într-un mod diferit. Începând cu versiunea 1.9, retry
funcționează numai cu un bloc begin
/rescue
, iar redo
funcționează numai în cadrul buclelor.
Cuvântul cheie next
Dacă doriți să treceți la următoarea iterație a buclei, spre deosebire de a vă deplasa înapoi la începutul celei curente, puteți folosi next
.
1 2 3 4 5 |
10.times do |i| puts "Iteration #{i}" next if i > 2 puts "Iteration done" end |
Aceasta va imprima:
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 ... |
Vezi cum contorul de iterații continuă să crească? În majoritatea cazurilor, utilizarea next
este ceea ce doriți. Uitați-vă la redo
dacă aveți nevoie de o buclă care se execută de un număr exact de ori sau dacă aveți nevoie de gestionarea erorilor atunci când iterați peste o matrice.
Sperăm că ați învățat ceva nou despre refacerea iterațiilor în bucle și ne-ar plăcea să știm ce părere aveți despre acest articol (sau despre oricare dintre celelalte din seria AppSignal Academy). Nu ezitați să ne spuneți ce credeți sau dacă aveți subiecte Ruby despre care ați dori să aflați mai multe.
.