谁能告诉我下面的片段
obj.send("#{method_name}")
现在和将来?
Send 是一个 Ruby 方法,它允许通过名称传递任何指定的参数来调用另一个方法。
class Klass def hello(*args) "Hello " + args.join(' ') end end k = Klass.new k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
来源
send向对象实例及其在类层次结构中的祖先发送消息,直到某个方法作出反应(因为它的名称与第一个参数匹配)。
send
实际上,这两句话是等价的:
1.send '+', 2 1.+(2) 1 + 2
请注意,send绕过了可见性检查,因此您也可以调用私有方法(对于单元测试很有用)。
如果在发送之前确实没有变量,这意味着使用了全局对象:
send :to_s # "main" send :class # Object
这是我认为最有用的特性之一。Send 方法是它可以动态调用。这可以为您节省大量的打字工作。最流行的用法之一。Send 方法是动态分配属性。例如:
class Car attr_accessor :make, :model, :year end
为了定期分配属性,需要
c = Car.new c.make="Honda" c.model="CRV" c.year="2014"
或者使用. send 方法:
c.send("make=", "Honda") c.send("model=", "CRV") c.send("year=","2014")
但它们都可以被以下内容所取代:
假设您的 Rails 应用程序需要从用户输入中为您的汽车类分配属性,那么您可以这样做
c = Car.new() params.each do |key, value| c.send("#{key}=", value) end
另一个例子,类似于安东尼奥 · 杰哈的 https://stackoverflow.com/a/26193804/1897857
是否需要读取对象的属性。
例如,如果您有一个字符串数组,如果您尝试遍历它们并在对象上调用它们,那么它将无法工作。
atts = ['name', 'description'] @project = Project.first atts.each do |a| puts @project.a end # => NoMethodError: undefined method `a'
但是,您可以 send对象的字符串:
atts = ['name', 'description'] @project = Project.first atts.each do |a| puts @project.send(a) end # => Vandalay Project # => A very important project
视图的另一个用例:
<%= link_to send("first_part_of_path_#{some_dynamic_parameters}_end_path", attr1, attr2), .... %>
允许您编写可伸缩的视图,这些视图可以处理所有类型的对象 与:
render 'your_view_path', object: "my_object"
send是“调用方法”的另一种方式,例如:
o = Object.new o.to_s # => "#<Object:0x00005614d7a24fa3>" # is equivalent to: o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
Send 生活在 Object 类 中。
这种方法的好处是可以将要调用的方法作为参数传入。下面是一个简单的例子:
def dynamically_call_a_method(method_name) o = Object.new o.send method_name end dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
可以传入要调用的方法。在这种情况下,我们通过 :to_s。这在进行 Ruby 元编程时非常方便,因为这允许我们根据不同的需求调用不同的方法。
:to_s
还可以使用 Send 来显示 Ruby 中的所有内容都是一个对象
1.send(:+, 1) ## -> 2 3.send(:*, 2) ## -> 6