Falamos sobre a palavra-chave retry
enquanto discutimos o retry após exceções. A sua contraparte pouco conhecida redo
funciona de forma semelhante, mas executa novamente iterações em loop em vez de blocos inteiros.
A palavra-chave redo
Como aprendemos no artigo anterior da Academia, retry
permite que você tente novamente um pedaço de código em um bloco:
1 2 3 4 5 6 |
begin puts "Iteration" raise rescue retry end |
Este exemplo imprime a palavra “Iteração” para o console antes de criar uma exceção. Os blocos de salvamento são executados, o que chama retry
e inicia o bloco novamente desde o início. Isto resulta no nosso programa imprimir infinitamente Iteration
. A palavra-chave redo
permite obter um efeito semelhante quando se utilizam loops. Isto é útil em situações em que você precisa tentar novamente enquanto itera, por exemplo.
1 2 3 4 |
10.times do |i| puts "Iteration #{i}" redo if i > 2 end |
Isto irá imprimir:
1 2 3 4 5 6 7 8 |
$ ruby redo.rb Iteration 0 Iteration 1 Iteration 2 Iteration 3 Iteration 3 Iteration 3 ... |
Nota como a contagem da iteração permanece a mesma? Voltará a execução para o início do laço. Esta variante do código usando retry
imprimirá exatamente a mesma saída:
1 2 3 4 5 6 7 8 |
10.times do |i| begin puts "Iteration #{i}" raise if i > 2 rescue retry end end |
Você pode usar redo
para implementar a repetição em um loop. No próximo exemplo, temos uma fila de trabalhos. Eles retornam ou :success
ou :failure
. Continuamos a mesma iteração do loop até que o trabalho tenha sucesso.
1 2 3 |
.each do |job| redo unless job.call == :success end |
Ruby 1.8
O comportamento de retry
e redo
mudou entre Ruby 1.8 e 1.9. Eles costumavam reiniciar a iteração do loop, mas ambos de uma forma diferente. De 1.9, retry
só funciona com um bloco de begin
/rescue
e redo
só funciona dentro de loops.
A próxima palavra-chave
Se você quiser passar para a próxima iteração do loop, ao invés de voltar ao início do atual, você pode usar next
.
1 2 3 4 5 |
10.times do |i| puts "Iteration #{i}" next if i > 2 puts "Iteration done" end |
Esta irá imprimir:
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 ... |
Ver como o contador de iteração continua a aumentar? Na maioria dos casos usando next
é o que você quer. Olhe para redo
se você precisa de um loop que executa um número exato de vezes ou precisa de manipulação de erros ao iterar sobre um array.
Esperamos que você tenha aprendido algo novo sobre refazer iterações em loops e gostaríamos de saber o que você achou deste artigo (ou de qualquer um dos outros da série AppSignal Academy). Por favor não hesite em nos dizer o que você pensa, ou se você tem algum assunto Ruby que você gostaria de aprender mais sobre.