2009-11-17 3 views
6
begin 
#some routine 
rescue 
retry 
#on third retry, output "no dice!" 
end 

Je veux faire en sorte que sur le "troisième" réessayer, imprimer un message.ruby: comment savoir si le script est en 3ème tentative?

+0

lieu de nouvelle tentative, mettre la chose dans une boucle de 3 x? –

+0

vous voulez réessayer dans une boucle trois fois? – puqt

Répondre

18

Peut-être pas la meilleure solution, mais un moyen simple est simplement de faire une variable tries.

tries = 0 
begin 
    # some routine 
rescue 
    tries += 1 
    retry if tries <= 3 
    puts "no dice!" 
end 
10
loop do |i| 
    begin 
    do_stuff 
    break 
    rescue 
    raise if i == 2 
    end 
end 

ou

k = 0 
begin 
    do_stuff 
rescue  
    k += 1 
    k < 3 ? retry : raise 
end 
+0

Le meilleur des premières réponses ... – DigitalRoss

+1

J'aime la première de ces alternatives parce qu'il est facile à retenir et à lire. Mais cela ne soulève pas l'erreur lors du dernier essai! – Peder

+1

C'est vrai, le premier n'est pas adapté à la plupart des codes réseau, mais il peut être utilisé lorsqu'aucune exception ne devrait être soulevée. – glebm

2
class Integer 
    def times_try 
    n = self 
    begin 
     n -= 1 
     yield 
    rescue 
     raise if n < 0 
     retry 
    end 
    end 
end 

begin 
    3.times_try do 
    #some routine 
    end 
rescue 
    puts 'no dice!' 
end 
1

Le joyau attempt est conçu pour cela, et offre la possibilité d'attendre entre les tentatives. Je ne l'ai pas utilisé moi-même, mais cela semble être une bonne idée.

Sinon, c'est le genre de choses que les blocs excelle, comme d'autres personnes l'ont démontré.

5
begin 
    #your code 
rescue 
    retry if (_r = (_r || 0) + 1) and _r < 4 # Needs parenthesis for the assignment 
    raise 
end 
3

Il existe une autre gemme nommée retry-this qui aide avec une telle chose.

ruby-1.9.2-p0 > require 'retry-this' 
ruby-1.9.2-p0 > RetryThis.retry_this(:times => 3) do |attempt| 
ruby-1.9.2-p0 >  if attempt == 3 
ruby-1.9.2-p0 ?>  puts "no dice!" 
ruby-1.9.2-p0 ?> else 
ruby-1.9.2-p0 >  puts "trying something..." 
ruby-1.9.2-p0 ?>  raise 'an error happens' # faking a consistent error 
ruby-1.9.2-p0 ?> end 
ruby-1.9.2-p0 ?> end 
trying something... 
trying something... 
no dice! 
=> nil 

La bonne chose au sujet d'un petit bijou par opposition à begin..rescue..retry première est que nous pouvons éviter une boucle infinie ou l'introduction d'une variable juste à cet effet.

1
def method(params={}) 
    tries ||= 3 
    # code to execute 
rescue Exception => e 
    retry unless (tries -= 1).zero? 
    puts "no dice!" 
end 
0
Proc.class_eval do 
    def rescue number_of_attempts=0 
    @n = number_of_attempts 
     begin 
     self.call 
     rescue => message 
     yield message, @n if block_given? 
     @n -= 1 
     retry if @n > 0 
     end 
    end 
end 

Et vous pouvez l'utiliser comme:

-> { raise 'hi' }.rescue(3) 
-> { raise 'hi' }.rescue(3) { |m, n| puts "message: #{m}, 
              number of attempts left: #{n}" } 
Questions connexes