send()在Ruby中做了什么?

问题描述 投票:77回答:6

有人可以告诉我什么

send("#{Model.find...}")

是吗?

ruby
6个回答
91
投票

send在类层次结构中向对象实例及其祖先发送消息,直到某些方法作出反应(因为它的名称与第一个参数匹配)。

实际上,这些线是等价的:

1.send '+', 2
1.+(2)
1 + 2

请注意,send绕过了可见性检查,因此您也可以调用私有方法(对单元测试很有用)。


如果在发送之前确实没有变量,则表示使用了全局Object:

send :to_s    # "main"
send :class   # Object

89
投票

send是一个ruby(没有rails)方法,允许按名称调用另一个方法。

从文档

   class Klass
     def hello(*args)
       "Hello " + args.join(' ')
     end
   end
   k = Klass.new
   k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"

http://corelib.rubyonrails.org/classes/Object.html#M001077


51
投票

我认为.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

8
投票

另一个例子,类似于Antonio Jha的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

1
投票

send是另一种调用方法的方法。最好通过示例说明:

o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"

这种方法的好处是您可以将要调用的方法作为参数传递。这是一个简单的例子:

def dynamically_call_a_method(name)
    o = Object.new
    o.send name 
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"

您可以传入要调用的方法。在这种情况下,我们通过了:to_s


0
投票

视图的另一个用例:

    <%= link_to 
    send("first_part_of_path_{some_dynamic_parameters}_end_path", 
    attr1, attr2), ....
    %>

允许。您可以编写可扩展视图,使用以下各种对象:

    render 'your_view_path', object: "my_object"
© www.soinside.com 2019 - 2024. All rights reserved.