我有以下代码:
for attribute in site.device_attributes
device.attribute
end
我希望代码用“attribute”的值替换方法名称。
我尝试了device."#{attribute}"
和各种排列。
这完全不可能吗?我错过了什么吗?
我考虑过覆盖method_missing,但是当我的问题是我需要调用“未知”方法时,我无法弄清楚这对我有什么帮助。
答案 0 :(得分:83)
您可以使用#send方法按方法名称调用对象的方法:
object.send(:foo) # same as object.foo
您可以将参数传递给调用的方法:
object.send(:foo, 1, "bar", 1.23) # same as object.foo(1, "bar", 1.23)
因此,如果在变量“attribute”中有属性名称,则可以使用
读取对象的属性object.send(attribute.to_sym)
并使用
写入属性的值object.send("#{attribute}=".to_sym, value)
在Ruby 1.8.6中,#send方法可以执行任何对象的方法,无论其可见性如何(例如,您可以调用私有方法)。这可能会在Ruby的未来版本中发生变化,您不应该依赖它。要执行私有方法,请使用#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
您可以使用public_send
来调用与可见性规则相关的方法。
object.public_send :public_foo # ok
object.public_send :private_bar # exception
答案 1 :(得分:19)
“发送”方法应该做你想要的:
object = "upcase me!"
method = "upcase"
object.send(method.to_sym) # => "UPCASE ME!"
答案 2 :(得分:7)
Matt和Maxim都是正确的,但遗漏了一个可以帮助您理解#send语法的细节:在Ruby中,调用方法实际上是在发送消息。 Rails上的Softies有一个relatively straightforward explanation of that。
答案 3 :(得分:2)
你也可以
device.instance_eval(attribute)