Gunther D. 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
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:
cl = Class.new
#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)
MyClass = create_class do
#This block sees the bindings that were present when it was
#created–no matter where the block ends up.
#In the current binding self=main. Remember
#blocks can see the variable bindings present outside the
obj = MyClass.new
1)The block isn’t executed until the yield, and when yield() is finally
called the block still sees self=main.
def statements create instance methods in the “current class”.
When self is not a class, the current class ends up being self’s
The block sees self=main, so the current class
inside the block is main’s class, which is Object. As a result, when
the block finally executes the def becomes an instance method of the
current class, which is Object. In other words, when the block
executes it’s the exact same thing as defining a method in the
top-level, where self=main and the current class=Object. And by ruby
dictate a top-level def becomes a private instance method of Object(the
method can be called anywhere–but you can’t use a receiver
to call the method).