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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:47:35  来源:igfitidea点击:

Variables in ruby method names

ruby-on-railsruby

提问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)