Gunther Diemant wrote in post #986869:
The greet method is a private method of Object not of MyClass.
Thanks. I didn't realize that Object#methods() returned only public
methods.
So it seems that the def in the block is evaluated in the toplevel scope
(where the block is defined) and not in the MyClass scope.
This is what I've come up with:
def create_class
cl = Class.new
cl.class_eval do
#In this block self=cl because that is
#what class_eval() does
yield #However, the block being yielded to
#doesn't care what the bindings are
#in this block--the block being yielded
#to got its bindings when the block was
#created. (bindings = variable_name/value pairs)
end
return cl
end
#self = main
MyClass = create_class do
#This block takes the bindings present when it was
#created along with it no matter where the block ends up,
#and in the current binding self=main. Remember
#blocks can see the variable bindings present outside the
#block.
def greet
puts 'hello'
end
end
obj = MyClass.new
obj.send(:greet) #hello
The block isn't executed until the yield, and when yield is finally
called the block sees self=main. def statements create instance methods
in the "current class", and when self is not a class, the current class
ends up being the class of self. Because self=main the current class
for the block is main's class, which is Object, so the def becomes in
instance method of Object. In other words, when that block executes
it's the exact same thing as defining a method in the top-level, and by
ruby dictate top-level methods are private methods of Object.
···
--
Posted via http://www.ruby-forum.com/\.