0

这是一个片段

def take_resource
  puts "resource taken"
end

def free_resource source
  puts "resource freed from #{source}"
end

def do_stuff
  tries = 0
  begin
    take_resource
    raise 'oops'
  rescue
    if tries < 3
      tries += 1
      free_resource 'rescue'
      retry
    end
    raise
  ensure
    free_resource 'ensure'
  end
end


do_stuff

# ~> -:13:in `do_stuff': oops (RuntimeError)
# ~>    from -:28:in `<main>'
# >> resource taken
# >> resource freed from rescue
# >> resource taken
# >> resource freed from rescue
# >> resource taken
# >> resource freed from rescue
# >> resource taken
# >> resource freed from ensure

在这里,我们看到当我们阻塞ensure时没有调用该子句。retry这是为什么?对此有合乎逻辑的解释吗?我认为这ensureensure有原因的:它总是运行。好吧,事实证明我错了。

在我们讨论的时候:你知道这个领域的其他问题(异常处理)吗?

4

1 回答 1

1

ensure在退出块时调用,无论是通过异常还是正常。retry只是将执行点转移到块的开头,因此您仍然在块中,并且ensure不会被调用。

考虑ensure存在以帮助在退出块时清理资源。如果您仍然处于障碍中,那么大概您仍在使用这些资源。

这是预期的行为。

这些关键字在 Programming Ruby 书 ( http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html )中有详细描述

于 2013-06-02T21:40:31.403 回答