以下代码生成9的输出。我理解send
只是调用方法:[]
,但我很困惑参数如何工作。
x = [1,2,3]
x.send :[]=,0,4 #why is x now [4,2,3]
x[0] + x.[](1) + x.send(:[],2) # 4 + 2 + 3
第2行和第3行如何运作?
答案 0 :(得分:4)
Object#send
提供了另一种调用方法的方法。
x.send :[]=,0,4
说,在[]=
上调用x
方法,并传递参数0
,4
,它相当于:
x[0] = 4
名称send
是因为在Ruby中,通过向对象发送消息来调用方法。该消息包含方法的名称以及方法可能需要的参数。这个想法来自SmallTalk。
答案 1 :(得分:4)
x.send(:[]=, 0, 4)
与
相同*x.[]=(0, 4)
具有
的语法糖x[0] = 4
应该熟悉其他语言。 括号当然是可选的。
.send
或.public_send
种类的优点是调用方法不必硬编码 - 它可以来自变量。
所有这些都与ruby的面向对象范式一致:对象通过发送消息相互通信,消息触发代码执行。
*差不多,#send
也会调用私有方法
答案 2 :(得分:3)
第2行是
x.send :[]=,0,4
这基本上是写这个的奇特方式:
x[0] = 4
(调用send
允许你调用私有方法,这是两种语法之间的一个区别。另外,一个对象可以想象地覆盖send
方法,这会破坏第一种语法。 )
因此,第2行具有将4写入数组中的第一个点的效果。
现在在第3行,我们看到我们正在加起来三件事。以下列出了我们要添加的内容:
x[0]
- 第一个元素x.[](1)
- 访问元素的另一种语法,用于访问第二个元素。此语法是传统的方法调用,其方法的名称恰好是[]
。x.send(:[], 2)
- 这显示了Ruby的另一个特性,即send
方法。它访问第三个元素。所以结果将是9,因为第三行添加了数组的第一,第二和第三个元素。
这些例子似乎说明了Ruby语言设计的一个有趣点。具体来说,数组访问是作为方法调用实现的。写入数组的首选语法是x[0] = 4
,读取的首选语法是x[0]
,因为该语法对于来自许多不同语言的程序员来说是熟悉的。但是,从数组读取和写入实际上是使用引擎下的方法调用实现的,这就是为什么可以使用一些看起来更像传统方法调用的其他语法。
传统方法调用如下所示:object.foo(arg1, arg2, arg3, ...)
。
上面显示的send
内容是Ruby的一个有用功能,它允许您使用符号指定要调用的方法,而不是强制您键入确切的名称。它还允许您调用私有方法。