lambda と Proc.new について
先日「Ruby の Proc.new と lambda って何が違うか解る?」と聞かれることがありました。私はてっきり lambda は Proc.new のシンタックスシュガーだと思い込んでいたのですが、ピッケル本を見てみるとどうやら違うようです。リファレンスマニュアルには
Proc を生成したメソッドからリターンしてしまった後は Proc からの return, retry は例外 LocalJumpError を発生させます。
とあります。例えば以下のコード。
実行してみると以下のようになります。
def foo
$a = Proc.new{ puts "proc";return "lambda"}
p $a.call
end
foo
p $a.call
% ruby lambda.rb
proc
proc
lambda.rb:2:in `foo': unexpected return (LocalJumpError)
from lambda.rb:6:in `call'
from lambda.rb:6
メソッド foo 内部で $a.call を実行した際は問題なく動作しますが、foo を抜けた後にコールすると return 時にはリファレンスマニュアルの通り LocalJumpError が発生します。
ここで気になるのは 3 行目の p $a.call。本来なら "lambda" と表示されて欲しいところです。Proc.new は生成したメソッドから抜けた後に return すると例外を投げるけれど、それ以前にメソッド内部からコールしても値を返さないのでしょうか。
ちなみに Proc.new を lambda にすると実行結果は以下のようになります。
% ruby lambda.rb
proc
"lambda"
proc
"lambda"
うーん、基本的に全部 lambda 使ってればいいような気がする。Proc.new を使う意味ってあるんでしょうか? proc はバージョンによって挙動が変わるので論外としても。