define_method と block_given?(Ruby)
Ruby でメソッドにブロックが与えられているかを確認する、Kernel#block_given?
というメソッドがある。
def foo p block_given? end foo #=>false foo {} #=>true
これが、メソッドをModule#define_method
で定義した場合、使えない。
define_method(:foo) do p block_given? end foo #=>false foo {} #=>false
というか、そもそもこの場合、yield
が使えないので、ブロックは Procオブジェクトで与えてやることになる。
define_method(:foo) do yield end #=>Invalid yield (SyntaxError)
define_method(:foo) do |&bk| bk.call end
では、こうするとして、block_given?
はどういう手段で代替するか。
それは、ブロックが与えられていない場合、bk
がnil
になることを使えば、実現できそうである。
define_method(:foo) do |&bk| p bk #ブロックが与えられていなければnilになる bk.call if bk end foo #=>nil foo {} #=>#<Proc:0x00007f1464fe6508>