Ruby does not 'ensure' when I 'retry' in 'rescue'

后端 未结 2 581
逝去的感伤
逝去的感伤 2020-12-31 12:48

Consider this begin-rescue-ensure block:

attempts=0
begin
  make_service_call()
rescue Exception
  retry unless attempts>2
  exit -1
ensure
  attemps += 1         


        
相关标签:
2条回答
  • 2020-12-31 12:55

    The ensure section is executed when leaving the begin statement (by any means) but when you retry, you're just moving around inside the statement so the ensure section will not be executed.

    Try this version of your example to get a better idea of what's going on:

    attempts = 0
    begin
      make_service_call()
    rescue Exception
      attempts += 1
      retry unless attempts > 2
      exit -1
    ensure
      puts "ensure! #{attempts}"
    end
    
    0 讨论(0)
  • 2020-12-31 13:12

    ensure code is executed once, just before the code block exits and it will be called at that time.

    But because of the unless attempts>2 condition, and the fact that ensure will only be called "just before the code exits" (e.g. due to exit -1) the attempts += 1 will not be executed, and so there is an infinite loop.

    ensure is like __finally in C++ : you could catch the exception and then use a goto : but finally will not be called until the function is actually about to exit.

    0 讨论(0)
提交回复
热议问题