たまにないですか?
3回ぐらいはとりあえずリトライして、その後はエラーとするか〜みたいな事。
そんな時どう書くのが良いのかな〜と。
というわけで、試しに書いてみました。
コード
module_retry.rb
module Retry
DEFAULT_RETRY_LIMIT = 3
# retry_limit以下の回数分yieldする.
# 指定が無い場合は、DEFAULT_RETRY_LIMIT回以下
def challenge(options = {})
raise ArgumentError.new "give block" unless block_given?
begin
count = count.to_i + 1
yield(count)
rescue => e
limit ||= (options[:retry_limit] || DEFAULT_RETRY_LIMIT)
if (count < limit)
retry
else
puts "over retry limit #{limit}."
raise
end
end
end
# includeしなくても、モジュールメソッドとしても呼び出したい時用
extend self
end
if __FILE__ == $0
def hoge
puts "hoge"
raise "raise error test1."
end
puts "test1:モジュールメソッドとして呼び出し"
Retry.challenge(retry_limit: 2){|times|
hoge
} rescue nil # エラーで停まらないように
include Retry
begin
puts "\ntest2:includeして呼び出し"
challenge{|times|
puts times
raise "raise error test2."
}
rescue => e
puts "#<#{e.class}: #{e.message}>"
puts " #{e.backtrace.join("\n ")}"
end
end
後は、このファイルをrequireすれば目標達成ですね。
実行結果
$ ruby module_retry.rb
test1:モジュールメソッドとして呼び出し
hoge
hoge
over retry limit 2.
test2:includeして呼び出し
1
2
3
over retry limit 3.
#<RuntimeError: raise error test2.>
module_retry.rb:42:in `block in <main>'
module_retry.rb:10:in `challenge'
module_retry.rb:40:in `<main>'
backtraceに余分なモノが挟まってしまうのが気になりますね。
他に良い書き方があるような気がします(=w=;