I'm reading the Metaprogramming section of Programming Ruby 1.9 and I'm having trouble understanding what's going on internally between class_eval
/class_exec
vs. instance_eval
/instance_exec
.
So first of all, my understanding is that def
adds a method to the method table of self
(the class object):
class A
puts self # => A
def foo; 42; end # added to the method table of self, so becomes an instance method
end
A.new.foo # => 42
And if we use class_eval
, we get the same behavior:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
But somehow in the instance_eval
case, things are different:
A.instance_eval do
puts self # => A
def baz; 42; end # added to the method table of an anonymous
# singleton class of self, so becomes a class method
end
puts A.baz # => 42
s = 'string'
s.instance_eval do ... end # same behavior, so now def creates an instance method
So I understand the functional difference between class_eval
and instance_eval
.
But the contexts inside the class_eval
and instance_eval
blocks look exactly the same to me -- in particular, self
points to the same object, and the local_variables
are the same. So what's going on inside the blocks (internally) that's making def
act different?
Is there some piece of documentation I could read? The RDoc for instance_eval and class_eval doesn't help. Looking at the source, instance_eval seems to set up a singleton class object whereas class_eval doesn't -- but is this difference visible outside the C code, on the Ruby level?