From: "Y. NOBUOKA" Date: 2011-04-24T01:59:32+09:00 Subject: [ruby-dev:43425] Re: (ruby-listから転載) lambda中のProc中のreturnの挙動について 信岡です。 [ruby-dev:35165] や [ruby-dev:35167] あたりを参考にしつつ問題点を考えたので まとめておきます。 補足説明的な扱いで。 考えるべき問題は 2 点あると思います。 == 1. lambda の中の proc からの return の挙動 (Ruby 1.9 と Ruby 1.8 で動作が異なる) == まず 1 つめは、lambda の中の proc からの return の挙動が Ruby 1.9 と Ruby 1.8 で異なる ということです。 現在の Ruby 1.8, 1.9 での動作をみると ・Ruby 1.9 では、proc 直下の return 式が評価されると、その proc を含んでいる最も内側の  lambda もしくはメソッドが終了する ・Ruby 1.8 では proc を含んでいるメソッドが終了する (lambda は無視される) となっています。 [ruby-dev:35175] でのまつもとさんの発言をみると、現在の Ruby 1.9 における 動作は仕様どおりなのだと思いますが、「では Ruby 1.8 における動作はこれでいいのかどうか」、 というのが 1 つ考えるべき点かと思います。 (ちなみに [ruby-dev:35175] のサンプルコードでは proc メソッドが使われていますが、Ruby 1.8 での proc メソッドは proc ではなく lambda を生成するので、[ruby-dev:35175] のサンプルコードを そのまま ruby 1.8 と 1.9 の両方で実行すると当然ながら異なる動作結果になると思います。) # サンプルコード def test1 b1 = lambda{ b2 = lambda{ Proc.new{ # この return 式は: # Ruby 1.8 ではメソッド test1 を抜ける <- これは仕様どおり? # Ruby 1.9 では内側の lambda を抜ける return :test1_proc }.call } $stdout << "test1-1 : #{b2.call()}\n" :test1_lambda # not reached on ruby 1.8, but reached on ruby 1.9 } $stdout << "test1-2 : #{b1.call()}\n" :test1 # not reached on ruby 1.8, but reached on ruby 1.9 end $stdout << "test1-3 : #{test1()}\n" 上記コードの実行結果は Ruby 1.8, 1.9 でそれぞれ以下のようになります。 ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux] test1-3 : test1_proc ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux] test1-1 : test1_proc test1-2 : test1_lambda test1-3 : test1 == 2. lambda の中で生成された proc の中の return が、lambda 実行終了後に評価された場合の動作 == 高尾さんが仰っている問題点の 2 つ目は、まさに [ruby-dev:35167] での話題と同じです。 ささださんが 『実装的な都合でいうと,「lambda から見て orphan をチェックするの大変そうだなぁ」 と思って,対応出来ていません.ただ,m() から抜けるふつーの return になっています.ちょっと, レアケース過ぎるかなあ,とも思うので,対応しなくても,特に困らないかとは思います.』 [ruby-dev:35173] と 仰って結局そのままになっているのだと思いますが、 ア. 現在の動作が仕様であって、今後もこのままである イ. 対応できるのであれば将来は LocalJumpError を発生させるようにするかもしれないので、  このようなコードは書くべきではない のどちらであるのかを明確に示して頂ければ Ruby ユーザーとしてはありがたいです。 (LocalJumpError を発生させるのが直感的な動作なので、現状ではエラーが発生しないとしても そのようなコードは書くべきではないと思いますが。。) 以上、補足と言いつつ長くなってしまいすみません。。 -- 信岡 ゆう (NOBUOKA Yu)