2012-02-22 16 views
12
class String 
    def hello 
    "world" 
    end 
end 

String.class_eval { 
    def world 
    "hello" 
    end 
} 

"a".world 
=> "hello" 
"b".hello 
=> "world" 

Parecen hacer lo mismo: agregar un método a una clase existente. Entonces, ¿cuál es la diferencia?parche de mono vs class_eval?

Respuesta

12

Con class_eval se pueden hacer cosas más dinámicos:

>> met = "hello" #=> "hello" 
>> String.class_eval "def #{met} ; 'hello' ; end" #=> nil 
>> "foo".hello #=> "hello" 
11

class_eval hacen conceptualmente reapertura de clase (o parches mono). Hay diferencias principalmente sintácticas. Si pasa una cadena al class_eval (como en el ejemplo de Michael), tiene la misma sintaxis dentro de la cadena que en el class String; ... end. Si pasa bloque: String.class_eval { ... } se compara la siguiente manera:

  • dentro del bloque class_eval variables locales exteriores son visibles
  • dentro de las variables locales exteriores de clase reabierto NO son visibles
  • dentro class_eval no se puede asignar constantes y variables de clase de ámbito a la clase
  • dentro de la clase reabierto usted PUEDE

sería interesante conocer las otras diferencias

0

Otras respuestas son buenas. Desea agregar que class_eval se puede usar cuando se quiere una clase de referencia no por su constante o para parchar un objeto particular.

p. Ej.

huh = String 
class huh 
end 
SyntaxError: (eval):2: class/module name must be CONSTANT 

huh.class_eval <<-eof 
def mamma 
puts :papa 
end 
eof 

"asdff".mamma 
=> papa 

Puede utilizar class_eval parchear objeto particular sin affectin clase raíz entera.

obj = "asd" 
obj.singleton_class.class_eval <<-eof 
def asd 
puts "gah" 
end 
undef_method :some_method 

Lo anterior es la misma como:

class << obj 
    ... 
end 

instance_eval tendrá un comportamiento ligeramente diferente por cierto uso.

Me parece preguntas y respuestas interesantes: How to monkey patch a ruby class inside a method

también hubo preguntas sobre instance_eval vs class_eval pero no tienen un enlace a mano.

Cuestiones relacionadas