10

次の begin-rescue-ensure ブロックを考えてみましょう。

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

そのコードをそのまま実行すると、「make_service_call()」という関数がないため、例外が発生します。それで、リトライします。しかし、「再試行」のために制御が「確実」にならないため、無限ループに陥ります。ブロックの一部を「保証」して、「開始」または「レスキュー」で何が起こっても、ブロック内のコードが実行されるようにするべきではありませんか?

もちろん、'begin' でカウントを増やすこともできますが、それは重要ではありません。明確にするために、「保証」について質問しているだけです。

4

2 に答える 2

18

ensureセクションは、ステートメントを離れるときに(何らかの方法で)実行されますbeginretry、ステートメント内を移動しているだけなので、確認セクションは実行されません。

このバージョンの例を試して、何が起こっているのかをよりよく理解してください。

attempts = 0
begin
  make_service_call()
rescue Exception
  attempts += 1
  retry unless attempts > 2
  exit -1
ensure
  puts "ensure! #{attempts}"
end
于 2011-06-03T06:12:12.050 に答える
3

ensureコードは、コード ブロックが終了する直前に 1 回実行されその時点で呼び出されます。

しかし、条件と、 「コードが終了する直前」にのみ呼び出されるというunless attempts>2事実(たとえば、 により) により、は実行されず、無限ループが発生します。ensureexit -1attempts += 1

ensure__finallyはC++のようなものです:catch例外を使用してからgoto:を使用できますがfinally、関数が実際に終了しようとするまで呼び出されません。

于 2011-06-03T06:13:11.963 に答える