Ruby: how do I know if there is a script on the third attempt?

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

I want to make it so that when I repeat the "third" I print a message.

+6
ruby
source share
8 answers

This may not be the best solution, but an easy way is to make only the tries variable.

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

or

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

There is another gem called retry-this that helps with such a thing.

 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 

The good thing about such a gemstone, unlike raw ones, begins .... rescue..retry is that we can avoid an infinite loop or introduce a variable for this very purpose.

+3
source share
 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 
+2
source share

The attempt stone is for this purpose and provides an opportunity of expectation between attempts. I have not used it myself, but it seems to be a great idea.

Otherwise, these are things that surpass everything, as other people have shown.

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

And then you can use it like:

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

All Articles