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>