ruby:如何知道脚本是否在第3次重试?

begin #some routine rescue retry #on third retry, output "no dice!" end 

我想这样做,以便在“第三次”重试时打印一条消息。

可能不是最好的解决方案,但一个简单的方法就是使一个tries变量。

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

要么

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

还有另一个名为retry的gem- 这有助于解决这个问题。

 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 

关于这样一个gem而不是raw begin..rescue..retry的好处是我们可以避免无限循环或为此目的引入一个变量。

 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 

gem 尝试就是为此而设计的,并提供了在尝试之间等待的选项。 我自己没有用过它,但这似乎是一个好主意。

否则,就像其他人所certificate的那样,这就是那种擅长的东西。

 def method(params={}) tries ||= 3 # code to execute rescue Exception => e retry unless (tries -= 1).zero? puts "no dice!" end 
 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 

然后你可以用它作为:

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