Disons que j'ai le hachage suivant:
{ :foo => 'bar', :baz => 'qux' }
Comment pourrais-je définir dynamiquement les clés et les valeurs pour qu'elles deviennent des variables d'instance dans un objet ...
class Example
def initialize( hash )
... magic happens here...
end
end
... pour que je me retrouve avec ce qui suit à l'intérieur du modèle ...
@foo = 'bar'
@baz = 'qux'
?
La méthode que vous recherchez est instance_variable_set
. Alors:
hash.each { |name, value| instance_variable_set(name, value) }
Ou, plus brièvement,
hash.each &method(:instance_variable_set)
Si le nom de votre variable d'instance ne contient pas le "@" (comme dans l'exemple de l'OP), vous devrez les ajouter, ce serait plus comme:
hash.each { |name, value| instance_variable_set("@#{name}", value) }
h = { :foo => 'bar', :baz => 'qux' }
o = Struct.new(*h.keys).new(*h.values)
o.baz
=> "qux"
o.foo
=> "bar"
Tu nous donnes envie de pleurer :)
Dans tous les cas, voir Object#instance_variable_get
et Object#instance_variable_set
.
Codage heureux.
Vous pouvez également utiliser send
qui empêche l'utilisateur de définir des variables d'instance inexistantes:
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
Utilisez send
lorsque dans votre classe il y a un setter comme attr_accessor
pour vos variables d'instance:
class Example
attr_accessor :foo, :baz
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
end