Please consider the following different ways to define method m:
Method 1:
class C def m; yield; end endMethod 2:
class C def initialize (class << self; self; end).class_eval do define_method(:m){|&b| b.call } end end endMethod 3:
class C def initialize (class << self; self; end).class_eval do define_method(:m){puts block_given?; yield} end end end
Then I can invoke m using Object#send.
o = C.new
o.send(:m) {puts 'test'}
While calling m using Method 1 or Method 2 works fine, Method 3 gives this error:
no block given (yield) (LocalJumpError)
I understand that a block is not an object, but instead just a part of method calling syntax and you cannot pass an implicit block from one function to another without writing something obscure like this:
def printer
yield
end
def proxy
printer &Proc.new
end
proxy { puts "&Proc.new probably creates Proc object from block"}
But in that case, why does Method 1 work? It would be awesome to get an answer which would explain what's happening under the hood.
sendto callm? It doesn't look like it has any meaning.class_evalon the class, rather than on the singleton class:self.class.class_eval do.