我刚刚读到了send
Ruby中的内容,在查看此代码时我仍然感到困惑(它来自测验但是过去截止日期)
x = [1,2,3]
x.send :[]=,0,2
x[0] + x.[](1) + x.send(:[],2)
Run Code Online (Sandbox Code Playgroud)
我明白第一行给x分配一个数组然后我不明白什么:[] = ,0,2
根本不知道我不明白为什么需要发送我不知道什么x.[](1)
做和x.send(:[],2)做到最后线
我真的很困惑,我无法在网上找到这些信息.
我发现了发送的内容,但我仍然有点困惑,并且对这个代码整体感到很困惑.
Chr*_*ald 57
首先,像[]
(数组索引)这样的东西[]=
只是Ruby中的方法.x
是一个Array
,并且数组有一个[]=
方法,它接受两个参数,一个索引和一个要设置的值.
使用send
允许您使用任意参数将任意"消息"(方法调用)传递给对象.
x.send :sort
例如,您可以调用将"sort"消息发送到数组.但是,Sort不需要任何参数,因此我们不必向其传递任何额外的参数.
x#[]=
另一方面,接受两个论点.它的方法可以被认为是这样的:
def []=(index, value)
self.set_value_at_index(index, value)
end
Run Code Online (Sandbox Code Playgroud)
所以,我们可以调用它send :[]=, 0, 2
,就像调用一样x[0] = 2
.整洁,对吧?
Eur*_*eka 24
在Ruby中,a[0] = 2
实际上是语法糖a.[]=(0, 2)
.
知道了这一点,这就是你的第二行所做的事情 - []=
正如你正确猜测的那样,它使用元编程调用带有两个参数的方法.
你的第三行也是如此:a[0]
Ruby中的语法糖x.[](0)
.
以下代码比您的示例更简单:
x = [1, 2, 3]
x[0] = 2
x[0] + x[1] + x[2]
Run Code Online (Sandbox Code Playgroud)
Sho*_*hoe 21
别担心.在这些情况下,Ruby可能有点棘手.让我们逐行检查代码:
x = [1,2,3]
x.send :[]=,0,2
x[0] + x.[](1) + x.send(:[],2)
Run Code Online (Sandbox Code Playgroud)
第一行很清楚:它为x分配了三个元素的数组.这就是它.
第二行调用传递符号的Object#send
方法x
(请记住,:
以ruby 开头的所有内容都是符号):[]=
,0
(a Fixnum
)和2
(另一个Fixnum
).
现在你只需要看看send方法的作用(正如你所说的那样):
调用由symbol标识的方法,并将指定的任何参数传递给它
这意味着它将调用由所标识的方法:[]=
和通过0
并2
给它.现在让我们来看看这个Array#[]=
方法.此方法定义(如果需要,可以由您重载)是:
class Array
# ...
def []=(a, b)
# ...
end
end
Run Code Online (Sandbox Code Playgroud)
这种方法是通过所谓send
的x.[]=(0, 2)
如果你问我,这是相当难看.这就是为什么Ruby定义了一个语法糖版本:x[0] = 2
一般来说:
x.[]=(a, b) --> x[a] = b
Run Code Online (Sandbox Code Playgroud)
在这种Array
情况下,我们还有以下内容:
x.[](a) --> x[a]
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都可以在特定的上下文中随意调用任何对您有意义的版本.
现在为第三行和最后一行:
x[0] + x.[](1) + x.send(:[],2)
Run Code Online (Sandbox Code Playgroud)
事情变得非常棘手.我们把它分成:
x[0]
x.[](1)
x.send(:[], 2)
第一个很直接.它返回数组的第一个元素.
第二个是我们之前看到的语法糖,它基本上可以转换为x[1]
返回数组的第二个元素.
第三个用于Object#send
调用[]
传递2
给它的方法.这意味着它调用了x.[](2)
哪种方式x[2]
.
代码
x = [1,2,3]
x.send :[]=,0,2
x[0] + x.[](1) + x.send(:[],2)
Run Code Online (Sandbox Code Playgroud)
可以转换为:
x.send(:[]=, a, b) --> x.[]=(a, b)
x.send(:[], a) --> x.[](a)
x.[]=(a, b) --> x[a] = b
x.[](a) --> x[a]
Run Code Online (Sandbox Code Playgroud)
至:
x = [1,2,3]
x[0] = 2
x[0] + x[1] + x[2]
Run Code Online (Sandbox Code Playgroud)
可以减少到:
2 + 2 + 3
Run Code Online (Sandbox Code Playgroud)
这导致:
7
Run Code Online (Sandbox Code Playgroud)
send
是一种在ruby中实现反射调用的方法.这样一行:
x.send :[]=,0,2
Run Code Online (Sandbox Code Playgroud)
相当于:
x[0] = 2
Run Code Online (Sandbox Code Playgroud)
你是这样读的:方法的名称是符号(在你的情况下[]=
),然后你传入参数 - 0和2.