ruby: как узнать, находится ли скрипт на 3-й повторной попытке? - PullRequest
6 голосов
/ 17 ноября 2009
begin
#some routine
rescue
retry
#on third retry, output "no dice!"
end

Я хочу сделать так, чтобы при «третьей» повторной попытке напечатать сообщение.

Ответы [ 8 ]

18 голосов
/ 17 ноября 2009

Возможно, не лучшее решение, но простой способ - просто создать tries переменную.

tries = 0
begin
  # some routine
rescue
  tries += 1
  retry if tries <= 3
  puts "no dice!"
end
10 голосов
/ 17 ноября 2009
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
5 голосов
/ 25 ноября 2010
begin
  #your code
rescue
  retry if (_r = (_r || 0) + 1) and _r < 4  # Needs parenthesis for the assignment
  raise
end
3 голосов
/ 16 декабря 2010

Существует еще один камень с именем retry-this , который помогает с такими вещами.

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 

Хорошая особенность такого драгоценного камня в отличие от необработанного begin..rescue..retry заключается в том, что мы можем избежать бесконечного цикла или введения переменной только для этой цели.

2 голосов
/ 17 ноября 2009
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 голос
/ 25 июня 2014
def method(params={})
  tries ||= 3
  # code to execute
rescue Exception => e
  retry unless (tries -= 1).zero?
  puts "no dice!"
end
1 голос
/ 17 ноября 2009

гем попытки предназначен для этого и предоставляет возможность ожидания между попытками. Я сам этим не пользовался, но, похоже, это отличная идея.

В остальном, именно в этом и преуспели блоки, как это продемонстрировали другие люди.

0 голосов
/ 15 сентября 2015
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}" }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...