We hebben het gehad over het retry
sleutelwoord tijdens het bespreken van het opnieuw proberen na uitzonderingen. Zijn weinig bekende tegenhanger redo
werkt op vergelijkbare wijze, maar voert lus-iteraties opnieuw uit in plaats van hele blokken.
Het redo keyword
Zoals we in het vorige Academy artikel hebben geleerd, kunt u met retry
een stuk code in een blok opnieuw proberen:
1 2 3 4 5 6 |
begin puts "Iteration" raise rescue retry end |
Dit voorbeeld drukt het woord “Iteration” af op de console voordat het een exception oproept. Het reddingsblok wordt uitgevoerd, waardoor retry
wordt aangeroepen en het blok weer van voren af aan begint. Dit resulteert in ons programma dat eindeloos Iteration
afdrukt. Met het redo
sleutelwoord kunt u een soortgelijk effect bereiken wanneer u lussen gebruikt. Dit is handig in situaties waarin u bijvoorbeeld tijdens het itereren opnieuw moet proberen.
1 2 3 4 |
10.times do |i| puts "Iteration #{i}" redo if i > 2 end |
Dit zal afdrukken:
1 2 3 4 5 6 7 8 |
$ ruby redo.rb Iteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 3 Iteration 3 ... |
Merkt u op dat het aantal iteraties hetzelfde blijft? Het zal de uitvoering terugstappen naar het begin van de lus. Deze variant van de code die retry
gebruikt, drukt exact dezelfde uitvoer af:
1 2 3 4 5 6 7 8 |
10.times do |i| begin puts "Iteration #{i}" raise if i > 2 rescue retry end end |
U kunt redo
gebruiken om het opnieuw proberen in een lus te implementeren. In het volgende voorbeeld hebben we een wachtrij van jobs. Ze geven ofwel :success
of :failure
terug. We blijven dezelfde iteratie van de lus herhalen totdat de job slaagt.
1 2 3 |
.each do |job| redo unless job.call == :success end |
Ruby 1.8
Het gedrag van retry
en redo
is tussen Ruby 1.8 en 1.9 veranderd. Vroeger startten ze de iteratie van de lus opnieuw, maar allebei op een andere manier. Vanaf 1.9, werkt retry
alleen met een begin
/rescue
blok en redo
werkt alleen binnen lussen.
Het volgende sleutelwoord
Als u naar de volgende iteratie van de lus wilt gaan, in plaats van terug te gaan naar het begin van de huidige, dan kunt u next
gebruiken.
1 2 3 4 5 |
10.times do |i| puts "Iteration #{i}" next if i > 2 puts "Iteration done" end |
Dit zal afdrukken:
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 ... |
Zie je hoe de iteratieteller blijft oplopen? In de meeste gevallen is next
wat u wilt. Kijk eens naar redo
als u een lus nodig hebt die een exact aantal keren wordt uitgevoerd of als er een foutafhandeling nodig is bij het itereren over een matrix.
We hopen dat u iets nieuws hebt geleerd over het opnieuw uitvoeren van iteraties in lussen en we horen graag wat u van dit artikel vond (of van een van de andere artikelen in de AppSignal Academy-serie). Aarzel niet om ons te laten weten wat je denkt, of als je Ruby-onderwerpen hebt waar je meer over zou willen leren.