可変長引数にはブロック引数は含まれない。
引数に「*」 を付けると「残りのすべての引数」が格納される可変長引数となりますが、これにはブロック引数は含まれません。たとえば「method_missing」を使って簡単なプロキシを書く場合、以下のように書いてしまうとブロック引数が渡されません。
# 委譲先クラス class Kitten def meow( prefix, &suffix ) "#{prefix} meow! #{ suffix && suffix.call}" end end # method_missingを使うプロキシ class Proxy def initialize( delegate ) @delegate = delegate end # ↓のように書いてしまうとブロック引数が転送されない。 def method_missing( name, *args ) @delegate.send( name, *args ) end end mii = Proxy.new Kitten.new puts mii.meow("a") # => a meow! puts mii.meow("a") { "x" } # => a meow!
実行結果です。
a meow! a meow!
ブロック引数を転送するには次のように書く必要があります。
class Proxy def initialize( delegate ) @delegate = delegate end # こう書けばOK def method_missing( name, *args, &block ) @delegate.send( name, *args, &block ) end end mii = Proxy.new Kitten.new puts mii.meow("a") # => a meow! puts mii.meow("a") { "x" } # => a meow! x
実行結果です。
a meow! a meow! x
ずっと勘違いしとった。orz..