不用担心。在这些情况下,Ruby 可能有点棘手。让我们逐行检查代码:
x = [1,2,3]
x.send :[]=,0,2
x[0] + x.[](1) + x.send(:[],2)
第一行
第一行对您来说很清楚:它将一个包含三个元素的数组分配给 x。仅此而已。
第二行
第二行调用传递符号的Object#send
方法(请记住,所有以 rubyx
开头的符号都是符号) 、(a ) 和(another )。
现在你只需要看看 send 方法做了什么(正如你所说的你已经完成了)::
:[]=
0
Fixnum
2
Fixnum
调用由符号标识的方法,将任何指定的参数传递给它
这意味着它将调用由标识的方法并将其:[]=
传递给它。现在让我们来看看方法。这个方法定义(如果你需要的话可以重载)是:0
2
Array#[]=
class Array
# ...
def []=(a, b)
# ...
end
end
如果你问我,这个方法是由send
as调用的,x.[]=(0, 2)
这很丑陋。这就是为什么 Ruby 定义了一个语法糖版本:x[0] = 2
一般来说:
x.[]=(a, b) --> x[a] = b
在这种Array
情况下,我们还有以下内容:
x.[](a) --> x[a]
在这两种情况下,您都可以在特定上下文中自由调用任何对您有意义的版本。
第三行
现在是第三行和最后一行:
x[0] + x.[](1) + x.send(:[],2)
事情变得非常棘手。我们把它分为:
x[0]
x.[](1)
x.send(:[], 2)
第一个非常简单。它返回数组的第一个元素。
第二个是我们之前看到的语法糖,基本上可以转换成x[1]
返回数组的第二个元素。
第三个用于Object#send
调用[]
传递2
给它的方法。这意味着它调用x.[](2)
which意味着x[2]
。
结论
编码
x = [1,2,3]
x.send :[]=,0,2
x[0] + x.[](1) + x.send(:[],2)
可以使用以下方法进行转换:
x.send(:[]=, a, b) --> x.[]=(a, b)
x.send(:[], a) --> x.[](a)
x.[]=(a, b) --> x[a] = b
x.[](a) --> x[a]
至:
x = [1,2,3]
x[0] = 2
x[0] + x[1] + x[2]
可以简化为:
2 + 2 + 3
这导致:
7