在Ruby中发送方法

我刚刚阅读了Ruby中send ,在查看这段代码的时候,我仍然感到困惑(这是来自一个测验,但是它的过期截止date)

 x = [1,2,3] x.send :[]=,0,2 x[0] + x.[](1) + x.send(:[],2) 

我明白,第一行为x分配一个数组,然后我不明白是什么:[] = ,0,2做到了,我不明白为什么发送需要在那里我没有得到什么x.[](1)做和x.send(:[],2)在最后一行

我真的很困惑,我只是不能在网上find这个信息。

我发现发送了什么,但是我仍然有点困惑,并且对这个代码整体有点困惑。

首先,像[] (数组索引)和[]=类的东西只是Ruby中的方法。 x是一个Array ,而数组有一个[]=方法,它接受两个参数,一个索引和一个值来设置。

使用send可以让任意parameter passing一个任意的“消息”(方法调用)到对象。

您可以调用x.send :sort ,例如,将“sorting”消息发送到数组。 sorting不需要任何参数,所以我们不必传递任何额外的东西。

另一方面, x#[]=接受两个参数。 其方法可以认为是这样的:

 def []=(index, value) self.set_value_at_index(index, value) end 

所以,我们可以用send :[]=, 0, 2来调用它,就像调用x[0] = 2 。 整洁,嗯?

在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] 

别担心 在这些情况下Ruby可能有点棘手。 让我们逐行检查代码:

 x = [1,2,3] x.send :[]=,0,2 x[0] + x.[](1) + x.send(:[],2) 

第一行

第一行很清楚:它为x分配了一个由三个元素组成的数组。 就是这个。

第二行

第二行调用x传递一个符号的Object#send方法(记住,所有以…开头的符号都是ruby中的符号) :[]=0 (一个Fixnum )和2 (另一个Fixnum )。
现在你只需要看一下发送方法是什么(就像你说过的那样):

调用由符号标识的方法,传递任何指定的参数

这意味着它将调用由:[]=标识的方法,并将02传递给它。 现在我们来看一下Array#[]=方法。 这个方法定义(如果你需要的话可以重载 )是:

 class Array # ... def []=(a, b) # ... end end 

这个方法是通过send作为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) 

事情变得非常棘手。 我们把它分成:

  1. x[0]
  2. x.[](1)
  3. 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) 

可以转换使用:

 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 

send是一种在ruby中实现reflection调用的方法。 因此这条线:

 x.send :[]=,0,2 

相当于:

 x[0] = 2 

你这样读:方法的名称是符号(在你的情况下[]= ),然后传递参数 – 0和2。

x [0] + x [1] + x [2] = 2 + 2 + 3 = 7我想这一定是答案