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.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.