Я читаю раздел метапрограммирования Программирование на Ruby 1.9 , и мне трудно понять, что происходит внутри между class_eval
/ class_exec
против instance_eval
/instance_exec
.
Итак, во-первых, я понимаю, что def
добавляет метод к таблице методов self
(объект класса):
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
И если мы используем class_eval
, мы получим такое же поведение:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
Но как-то в instance_eval
случае все иначе:
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
Итак, я понимаю функциональную разницу между class_eval
и instance_eval
.
Но контексты внутри блоков class_eval
и instance_eval
выглядят для меня точно одинаково - в частности, self
указывает на один и тот же объект, а local_variables
одинаковы , Так что же происходит внутри (внутри) блоков, что заставляет def
действовать иначе?
Есть ли какая-нибудь документация, которую я мог бы прочитать? RDoc для instance_eval и class_eval не помогает. Глядя на источник, instance_eval , кажется, устанавливает объект класса singleton, тогда как class_eval - нет, но видна ли эта разница вне кода C, на уровне Ruby?