I have the following code:
for attribute in site.device_attributes
device.attribute
end
where I would like the code to substitute the value o
you can also do
device.instance_eval(attribute)
Matt and Maxim are both correct, but leave out a detail that might help you get your head around the #send syntax: In Ruby, calling a method is really sending a message. Softies on Rails has a relatively straightforward explanation of that.
The "send" method should do what you're looking for:
object = "upcase me!"
method = "upcase"
object.send(method.to_sym) # => "UPCASE ME!"
You can use #send method to call object's method by method's name:
object.send(:foo) # same as object.foo
You can pass arguments with to invoked method:
object.send(:foo, 1, "bar", 1.23) # same as object.foo(1, "bar", 1.23)
So, if you have attribute name in variable "attribute" you can read object's attribute with
object.send(attribute.to_sym)
and write attribute's value with
object.send("#{attribute}=".to_sym, value)
In Ruby 1.8.6 #send method can execute any object's method regardless of its visibility (you can e.g. call private methods). This is subject to change in future versions of Ruby and you shouldn't rely on it. To execute private methods, use #instance_eval:
object.instance_eval {
# code as block, can reference variables in current scope
}
# or
object.instance_eval <<-CODE
# code as string, can generate any code text
CODE
You can use public_send
to call methods with regard to visibility rules.
object.public_send :public_foo # ok
object.public_send :private_bar # exception