Retry
如果你认为错误情况可能是暂时的或者可以被纠正(由用户),你可以使用关键字 retry
重新运行 begin..end
块中的所有代码,如此示例中如果发生 ZeroDivisionError 等错误则会提示用户重新输入一个值:
retry.rb
def doCalc
begin
print( "Enter a number: " )
aNum = gets().chomp()
result = 100 / aNum.to_i
rescue Exception => e
result = 0
puts( "Error: " + e + "\nPlease try again." )
retry # retry on exception
else
msg = "Result = #{result}"
ensure
msg = "You entered '#{aNum}'. " + msg
end
return msg
end
当然,存在这样的危险:错误可能不像你想象的那样是暂时的,如果你使用 retry
,你必须要提供明确定义的退出(exit)条件,以确保代码在固定次数的尝试后停止执行。
例如,你可以在 begin
子句中递增一个局部变量(如果这样做,请确保它在任何可能产生异常的代码之前递增,因为一旦发生异常,那些剩下的预先为 rescue
子句关联的代码将被跳过!)。然后在 rescue
部分测试该变量的值,如下所示:
rescue Exception => e
if aValue < someValue then
retry
end
这是一个完整的示例,其中我测试名为 tries
的变量的值,以确保在异常处理块退出之前在不出错的情况下尝试重新运行代码不超过三次:
def doCalc
tries = 0
begin
print( "Enter a number: " )
tries += 1
aNum = gets().chomp()
result = 100 / aNum.to_i
rescue Exception => e
msg = "Error: " + e
puts( msg )
puts( "tries = #{tries}" )
result = 0
if tries < 3 then # set a fixed number of retries
retry
end
else
msg = "Result = #{result}"
ensure
msg = "You entered '#{aNum}'. " + msg
end
return msg
end