Metaprogramowanie Ruby: dynamiczne nazwy zmiennych instancji
Powiedzmy, że mam następujący hash:
{ :foo => 'bar', :baz => 'qux' }
Jak mogę dynamicznie ustawić klucze i wartości, aby stały się zmiennymi instancji w obiekcie...
class Example
def initialize( hash )
... magic happens here...
end
end
... tak, że kończy się z następujących wewnątrz modelu...
@foo = 'bar'
@baz = 'qux'
?
83
4 answers
Metoda, której szukasz jest instance_variable_set
. Więc:
hash.each { |name, value| instance_variable_set(name, value) }
Lub, w skrócie,
hash.each &method(:instance_variable_set)
Jeśli w nazwach zmiennych instancji brakuje " @ " (tak jak w przykładzie OP), musisz je dodać, więc byłoby to bardziej jak:
hash.each { |name, value| instance_variable_set("@#{name}", value) }
153
Author: Chuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-06 04:22:26
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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"
12
Author: DigitalRoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 02:54:49
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 02:54:49
You make we want to cry:)
W każdym razie patrz Object#instance_variable_get
oraz Object#instance_variable_set
.
Możesz również użyć send
, co uniemożliwia użytkownikowi ustawienie nieistniejących zmiennych instancji:
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
Użyj send
, gdy w twojej klasie znajduje się setter attr_accessor
dla zmiennych instancji:
class Example
attr_accessor :foo, :baz
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
end
5
Author: Asarluhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-20 13:11:32
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-20 13:11:32