@Readonly
Si votre utilisation de la classe "Monobjet" est un usage de la classe ouverte, alors s'il vous plaît noter que vous êtes la redéfinition de la méthode initialize.
En Ruby, il n'y a pas une telle chose comme la surcharge... seulement dominante, ou la redéfinition... en d'autres termes, il ne peut être de 1 instance de toute méthode, donc, si vous le redéfinir, il est redéfini... et la méthode initialize est pas différent (même si c'est ce que la nouvelle méthode de la Classe des objets d'usage).
Donc, jamais de redéfinir une méthode existante sans crénelage d'abord... au moins si vous voulez accéder à la définition originelle. Et la redéfinition de la méthode initialize d'un inconnu de classe peut être très risqué.
En tout cas, je pense que j'ai une solution beaucoup plus simple pour vous, qui utilise le réel métaclasse pour définir singleton méthodes:
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
Vous pouvez utiliser à la fois la métaclasse et ouvrir des classes pour obtenir encore plus difficile et faire quelque chose comme:
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" })
Le ci-dessus est essentiellement d'exposer la métaclasse via le "métaclasse" méthode, puis en l'utilisant dans define_attributes pour définir dynamiquement un ensemble d'attributs avec attr_accessor, puis en l'invoquant l'attribut setter par la suite avec la valeur associée dans la table de hachage.
En Ruby, vous pouvez faire preuve de créativité et faire la même chose de plusieurs manières différentes ;-)
Pour info, au cas où vous ne le saviez pas, à l'aide de la métaclasse comme je l'ai fait signifie que vous êtes en agissant uniquement sur l'instance donnée de l'objet. Ainsi, en invoquant define_attributes ne définir des attributs pour ce cas particulier.
Exemple:
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!