@Readonly
Si su uso de "MiObjeto clase" es un uso de una clase abierta, a continuación, tenga en cuenta que está redefiniendo el método initialize.
En Ruby, no existe la sobrecarga ... solo anulación, o redefinición ... en otras palabras, solo puede haber 1 instancia de un método determinado, por lo que si la redefines se redefine. .y el método de inicialización no es diferente (aunque es lo que usa el nuevo método de objetos de clase).
Por lo tanto, nunca redefina un método existente sin alias primero ... al menos si desea acceder a la definición original. Y redefinir el método de inicialización de una clase desconocida puede ser bastante arriesgado.
En cualquier caso, creo que tengo una solución mucho más simple para usted, que utiliza la metaclase real para definir métodos simples:
m = MyObject.new
metaclass = class << m; self; end
metaclass.send :attr_accessor, :first, :second
m.first = "first"
m.second = "second"
puts m.first, m.second
Se puede utilizar tanto la metaclase y clases abiertas para obtener aún más complicado y hacer algo como:
class MyObject
def metaclass
class << self
self
end
end
def define_attributes(hash)
hash.each_pair { |key, value|
metaclass.send :attr_accessor, key
send "#{key}=".to_sym, value
}
end
end
m = MyObject.new
m.define_attributes({ :first => "first", :second => "second" })
lo anterior es, básicamente, la exposición de la metaclase a través del método "metaclase", a continuación, utilizarlo en definir _ atributos para definir dinámicamente un montón de atributos con attr _ acce ssor, y luego invocando el setter de atributos luego con el valor asociado en el hash.
con Ruby puede ser creativo y hacer lo mismo de muchas maneras diferentes ;-)
su información, en caso de que no lo sabía, utilizando la metaclase como lo he hecho significa que sólo está actuando en la instancia dada del objeto. Por lo tanto, invocar los atributos de definir _ solo definirá esos atributos para esa instancia particular.
Ejemplo:
m1 = MyObject.new
m2 = MyObject.new
m1.define_attributes({:a => 123, :b => 321})
m2.define_attributes({:c => "abc", :d => "zxy"})
puts m1.a, m1.b, m2.c, m2.d # this will work
m1.c = 5 # this will fail because c= is not defined on m1!
m2.a = 5 # this will fail because a= is not defined on m2!
Puede que no se haya aclarado, pero literalmente puede volver a abrir la clase en cualquier momento con la clase ClassName; (cosas nuevas aquí); fin. Esto agrega cosas a una clase existente. Limpio, ¿eh? – webmat
Sí, el webmat es correcto ... Todas las respuestas a continuación funcionan en cualquier archivo que desee cuando lo desee ... debido a algo llamado "clases abiertas", lo que significa que puede modificar una clase en cualquier momento que desee a través de la palabra clave class. –