Ruby Metaprogramming: nombres de variables de instancia dinámicas
Digamos que tengo el siguiente hash:
{ :foo => 'bar', :baz => 'qux' }
¿Cómo podría configurar dinámicamente las claves y los valores para que se conviertan en variables de instancia en un objeto?..
class Example
def initialize( hash )
... magic happens here...
end
end
... así que termino con lo siguiente dentro del modelo...
@foo = 'bar'
@baz = 'qux'
?
4 answers
El método que está buscando es instance_variable_set
. Entonces:
hash.each { |name, value| instance_variable_set(name, value) }
O, más brevemente,
hash.each &method(:instance_variable_set)
Si a los nombres de las variables de instancia les falta el " @ " (como en el ejemplo del OP), tendrá que agregarlos, por lo que sería más como:
hash.each { |name, value| instance_variable_set("@#{name}", value) }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-06 04:22:26
h = { :foo => 'bar', :baz => 'qux' }
o = Struct.new(*h.keys).new(*h.values)
o.baz
=> "qux"
o.foo
=> "bar"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-19 02:54:49
Haces que queramos llorar:)
En cualquier caso, ver Object#instance_variable_get
y Object#instance_variable_set
.
Feliz codificación.
También puede usar send
que evita que el usuario establezca variables de instancia inexistentes:
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
Use send
cuando en su clase haya un setter como attr_accessor
para sus variables de instancia:
class Example
attr_accessor :foo, :baz
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-20 13:11:32