Rubyのメソッド呼出しとブロックについて

自分のためのメモ。

メソッド定義の最後の引数にアンパサンドが付いている場合:

メソッドに関連付けられたブロックが手続きオブジェクトに変換されて、引数に格納される。

メソッド呼出しの最後の引数にアンパサンドが付いている場合(引数は手続きオブジェクト):

手続きオブジェクトはブロックとしてメソッドに渡される。

def foo(a)
  a.call("in foo")
end

def bar(&a)
  a.call("in bar")
end

aProc = proc { |s| p s }

foo(aProc)
foo(proc { |s| p s })

bar(&aProc)
bar(&(proc { |s| p s}))
bar { |s| p s }

実行結果は以下のとおり。

"in foo"
"in foo"
"in bar"
"in bar"
"in bar"

イメージとしては、まず「ブロックの関連付け - yieldによるブロック呼出し」というメソッドに手続きを渡すデフォルトの方法があり、もう一つの「手続きオブジェクトによる手続きの引渡し」という方法がデフォルトの方法を利用するときに&をつける感じ。