当我”救援”重试’时,Ruby不会“确保”
考虑一下这个begin-rescue-ensure块:
attempts=0 begin make_service_call() rescue Exception retry unless attempts>2 exit -1 ensure attemps += 1 end
如果按原样运行该代码,则会引发exception,因为没有名为’make_service_call()’的函数。 所以,它重试。 但它会陷入无限循环,因为控制永远不会因为“重试”而“确保”。 不管“开始”或“救援”发生什么,不应该“确保”块的一部分确保其中的代码被执行?
当然,我可以在’开始’中递增计数 – 这不是重点。 我只想问一下’确保’的问题,以便澄清一下。
在离开begin
语句时(通过任何方式)执行ensure
部分,但是当你retry
,你只是在语句内移动,所以不会执行ensure部分。
试试这个版本的示例,以便更好地了解正在发生的事情:
attempts = 0 begin make_service_call() rescue Exception attempts += 1 retry unless attempts > 2 exit -1 ensure puts "ensure! #{attempts}" end
ensure
代码执行一次,就在代码块退出之前,它将在那时被调用。
但是由于unless attempts>2
条件,并且ensure
将仅在“代码退出之前”被调用(例如,由于exit -1
),因此将不会执行attempts += 1
,因此存在无限环。
ensure
在C ++中就像__finally
一样:你可以catch
exception然后使用goto
:但是在函数实际即将退出之前finally
不会被调用。