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何故ですか?これには論理的な説明がありますか?私はそれが理由ensureで呼ばれていると思いました:それは常に実行されます。ensureさて、私が間違っていたことがわかりました。

そして、私たちがそれに取り組んでいる間、あなたはこの分野の他の落とし穴(例外処理)について知っていますか?

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 に答える