Disons que j’ai le hachage suivant:
{ :foo => 'bar', :baz => 'qux' }
Comment pourrais-je définir dynamicment les clés et les valeurs pour qu’elles deviennent des variables d’instance dans un object …
class Example def initialize( hash ) ... magic happens here... end end
… pour que je me retrouve avec les éléments suivants dans le 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 les noms de variables de votre instance ne contiennent pas le “@” (comme dans l’exemple de l’OP), vous devrez les append, cela ressemblera davantage à:
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 fais envie de pleurer 🙂
Dans tous les cas, voir Object#instance_variable_get
et Object#instance_variable_set
.
Heureux codage
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
quand 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