Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
Simplemente en función del nombre de los métodos, Esperaría que class_eval le permita agregar un método de clase a Foo y instance_eval para permitirle agregar un método de instancia a Foo. Pero parecen hacer lo opuesto.¿Cómo entender la diferencia entre class_eval() y instance_eval()?
En el ejemplo anterior si llama a class_bar en la clase Foo obtiene un error de método indefinido y si llama a instance_bar en la instancia devuelta por Foo.new, también obtiene un error de método indefinido. Ambos errores parecen contradecir una comprensión intuitiva de lo que class_eval y instance_eval deberían hacer.
¿Cuál es la diferencia entre estos métodos?
Documentación para class_eval:
mod.class_eval (string [, nombre de archivo [, lineno]]) => obj
Evalúa la cadena o bloque en el contexto de mod . Esto se puede usar para agregar métodos a una clase.
Documentación para instance_eval:
obj.instance_eval {| | bloque} => obj
evalúa una cadena que contiene de rubíes código fuente, o el bloque dado, en el contexto del receptor (obj). Para establecer el contexto, , la variable self se establece en obj, mientras que se está ejecutando el código, dando al código acceso a las variables de instancia de obj.
Esta es una excelente explicación. Gracias. Te seguí hasta el último párrafo donde intentas explicar por qué instance_eval define los métodos de clase cuando se llama a una clase. La última línea es particularmente difícil de digerir: "Llamar a un método de clase es un error, es solo un método de instancia en esa instancia de Clase particular". ¿Quiere decir que todos los métodos de clase no son más que eso? –
Sí, exactamente, eso es todo lo que son. Trataré de hacerlo más claro mañana. – tomafro
Fantástico: acabo de agregar una nueva pregunta específicamente para ese tema: "¿Por qué instance_eval() define un método de clase cuando se llama a una clase?" http://stackoverflow.com/questions/900704/why-does-instanceeval-define-a-class-method-when-called-on-a-class. –