ruby 方法名称中的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/300705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Variables in ruby method names
提问by salt.racer
I have the following code:
我有以下代码:
for attribute in site.device_attributes
device.attribute
end
where I would like the code to substitute the value of "attribute" for the method name.
我希望代码将“属性”的值替换为方法名称。
I have tried device."#{attribute}"and various permutations.
我已经尝试过device."#{attribute}"各种排列。
Is this completely impossible? Am I missing something?
这是完全不可能的吗?我错过了什么吗?
I have considered overriding method_missing, but I can't figure out how that would actually help me when my problem is that I need to call an "unknown" method.
我已经考虑过覆盖 method_missing,但是当我的问题是我需要调用一个“未知”方法时,我无法弄清楚这实际上对我有什么帮助。
回答by Maxim Kulkin
You can use #send method to call object's method by method's name:
您可以使用 #send 方法通过方法名称调用对象的方法:
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
因此,如果变量“attribute”中有属性名称,则可以使用以下命令读取对象的属性
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:
在 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
Update
更新
You can use public_sendto call methods with regard to visibility rules.
您可以使用public_send调用与可见性规则相关的方法。
object.public_send :public_foo # ok
object.public_send :private_bar # exception
回答by Matt Campbell
The "send" method should do what you're looking for:
“发送”方法应该做你正在寻找的:
object = "upcase me!"
method = "upcase"
object.send(method.to_sym) # => "UPCASE ME!"
回答by bradheintz
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.
Matt 和 Maxim 都是正确的,但省略了一个可能有助于您了解 #send 语法的细节: 在 Ruby 中,调用方法实际上是发送消息。Softies on Rails 对此有一个相对简单的解释。
回答by David Nehme
you can also do
你也可以这样做
device.instance_eval(attribute)

