在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 )。 
 现在你只需要看一下发送方法是什么(就像你说过的那样): 
调用由符号标识的方法,传递任何指定的参数
 这意味着它将调用由:[]=标识的方法,并将0和2传递给它。 现在我们来看一下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) 
事情变得非常棘手。 我们把它分成:
-  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) 
可以转换使用:
 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我想这一定是答案