Let's say I have the following hash:
{ :foo => 'bar', :baz => 'qux' }
How could I dynamically set the keys and values to become instance variables in an object...
class Example
def initialize( hash )
... magic happens here...
end
end
... so that I end up with the following inside the model...
@foo = 'bar'
@baz = 'qux'
?
The method you are looking for is instance_variable_set
. So:
hash.each { |name, value| instance_variable_set(name, value) }
Or, more briefly,
hash.each &method(:instance_variable_set)
If your instance variable names are missing the "@" (as they are in the OP's example), you'll need to add them, so it would be more like:
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"
You make we want to cry :)
In any case, see Object#instance_variable_get
and Object#instance_variable_set
.
Happy coding.
You can also use send
which prevents the user from setting non-existent instance variables:
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
Use send
when in your class there is a setter like attr_accessor
for your instance variables:
class Example
attr_accessor :foo, :baz
def initialize(hash)
hash.each { |key, value| send("#{key}=", value) }
end
end