estoy leyendo la sección de Metaprogramación de programación Ruby 1.9 y estoy teniendo problemas para entender lo que está pasando internamente entre class_eval
/class_exec
vs instance_eval
/instance_exec
.de Ruby definición y instance_eval vs class_eval
Así que en primer lugar, mi opinión es que def
añade un método para la tabla de métodos de self
(la clase de objeto):
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
Y si usamos class_eval
, obtenemos el mismo comportamiento:
A.class_eval do
puts self # => A
def bar; 42; end # same as above
end
A.new.bar # => 42
Pero de alguna manera en el caso instance_eval
, las cosas son diferentes:
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
Así que entiendo la diferencia funcional entre class_eval
y instance_eval
.
Pero los contextos dentro de los bloques class_eval
y instance_eval
vistazo exactamente lo mismo para mí - en particular, self
puntos para el mismo objeto, y el local_variables
son los mismos. Entonces, ¿qué está pasando dentro de los bloques (internamente) que está haciendo que def
actúe diferente?
¿Hay alguna documentación que pueda leer? El RDoc para instance_eval y class_eval no ayuda. Al mirar la fuente, instance_eval parece configurar un objeto de clase singleton, mientras que class_eval no lo hace, pero ¿esta diferencia es visible fuera del código C, en el nivel de Ruby?
Hm, ya veo, eso tiene sentido. ¿Hay alguna manera de inspeccionar esa "clase actual" en el código de Ruby? –
Creo que en 'A.instance_eval', ¿quiso escribir' #defs aquí, vaya a la clase E de A' ¿O estoy equivocado? –
No es exactamente simple, publicaré algunos enlaces relevantes en la respuesta –