他力本願メソッドによるRubyの習得その2:yieldとブロック.callとProc.new.callとproc.callとlambda.callの動作について

Rubyリファレンスマニュアル - FAQ::イテレータにある↓この例も何でこうなるのか(or 何でこうなるようにしたのか)よくわかりません…。(Ruby 1.9はともかく1.8としては)バージョンが古いせいじゃないですよね。Ruby難しいです。;_;

> ruby --version
ruby 1.8.2 (2005-04-11) [i386-linux]
> irb1.8 
irb(main):001:0> def a (&b)
irb(main):002:1>   yield
irb(main):003:1>   b.call
irb(main):004:1>   Proc.new.call
irb(main):005:1>   proc.call
irb(main):006:1>   lambda.call
irb(main):007:1> end
=> nil
irb(main):008:0> a { print "test\n" }
test
test
test
(irb):5: warning: tried to create Proc object without a block
test
(irb):6: warning: tried to create Proc object without a block
test
=> nil
irb(main):009:0> 

P.S.

> ./ruby --version
ruby 1.9.0 (2007-06-14 patchlevel 0) [i686-linux]
> cat ~/tmp/proctest.rb
def a (&b)
  yield
  b.call
  Proc.new.call
  proc.call
  lambda.call
end
a { print "test\n" }
> ./ruby ~/tmp/proctest.rb
test
test
test
test
/home/sumii/tmp/proctest.rb:6: warning: tried to create Proc object without a block
test

要するに

  • やはりRuby 1.8ではProc.new != proc == lambdaだが、1.9ではProc.new == proc != lambda
  • Proc.newやlambdaに引数を与えなかったら「デフォルトのブロック引数」が渡されるけど、lambdaでは警告される

ということだろうか。Ruby 1.8と1.9のそれぞれについて、

  • 組み込みのyield
  • Procのyield
  • Procのcall
  • Proc.new
  • proc
  • lambda

の間の関係をまとめた表を希望(←自分で作れ)。