Nous avons parlé du mot-clé retry
en abordant la réessai après des exceptions. Son homologue peu connu redo
fonctionne de manière similaire, mais ré-exécute les itérations de la boucle au lieu de blocs entiers.
Le mot-clé redo
Comme nous l’avons appris dans l’article précédent de l’Académie, retry
vous permet de réessayer un morceau de code dans un bloc :
1 2 3 4 5 6 |
begin puts "Iteration" raise rescue retry end |
Cet exemple imprime le mot « Iteration » à la console avant de lever une exception. Le bloc de sauvetage s’exécute, ce qui appelle retry
et recommence le bloc depuis le début. Il en résulte que notre programme imprime sans fin Iteration
. Le mot-clé redo
vous permet d’obtenir un effet similaire lorsque vous utilisez des boucles. Ceci est utile dans les situations où vous avez besoin de réessayer tout en itérant par exemple.
1 2 3 4 |
10.times do |i| puts "Iteration #{i}" redo if i > 2 end |
Ceci imprimera :
1 2 3 4 5 6 7 8 |
$ ruby redo.rb Iteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 3 Iteration 3 ... |
Vous remarquez que le nombre d’itérations reste le même ? Il recule l’exécution jusqu’au début de la boucle. Cette variante du code utilisant retry
imprimera exactement la même sortie:
1 2 3 4 5 6 7 8 |
10.times do |i| begin puts "Iteration #{i}" raise if i > 2 rescue retry end end |
Vous pouvez utiliser redo
pour implémenter le retrying dans une boucle. Dans l’exemple suivant, nous avons une file d’attente de travaux. Ils retournent soit :success
soit :failure
. Nous continuons à relancer la même itération de la boucle jusqu’à ce que le job réussisse.
1 2 3 |
.each do |job| redo unless job.call == :success end |
Ruby 1.8
Le comportement de retry
et redo
a changé entre Ruby 1.8 et 1.9. Ils avaient l’habitude de relancer l’itération de la boucle, mais tous deux d’une manière différente. À partir de la 1.9, retry
ne fonctionne qu’avec un bloc begin
/rescue
et redo
ne fonctionne qu’à l’intérieur des boucles.
Le mot-clé next
Si vous voulez passer à l’itération suivante de la boucle, par opposition au retour au début de l’itération actuelle, vous pouvez utiliser next
.
1 2 3 4 5 |
10.times do |i| puts "Iteration #{i}" next if i > 2 puts "Iteration done" end |
Ceci va imprimer :
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 ... |
Vous voyez comment le compteur d’itération continue de s’incrémenter ? Dans la plupart des cas, utiliser next
est ce que vous voulez. Regardez redo
si vous avez besoin d’une boucle qui s’exécute un nombre exact de fois ou si vous avez besoin d’une gestion des erreurs lors de l’itération sur un tableau.
Nous espérons que vous avez appris quelque chose de nouveau sur la reprise des itérations dans les boucles et nous aimerions savoir ce que vous avez pensé de cet article (ou de tout autre de la série AppSignal Academy). N’hésitez pas à nous faire savoir ce que vous pensez, ou si vous avez des sujets Ruby sur lesquels vous aimeriez en savoir plus.