2010-08-11 59 views
5

今天我看到了一个ruby代码片断。这个红宝石注入魔法是如何工作的?

[1,2,3,4,5,6,7].inject(:+) 

=> 28

[1,2,3,4,5,6,7].inject(:*) 

=> 5040

这里的注入是不同于我以前见过完全不同,就像

[1,2,3,4,5,6,7].inject {|sum, x| sum + x} 

请解释它是如何工作的?

+0

我不知道是否有一个特殊的名称(如果你想谷歌的话),而不是'Symbol#to_proc'。 – 2010-08-11 07:36:05

回答

6

没有魔法,符号(方法)只是其中一个可能的参数。这是从文档:

# enum.inject(initial, sym) => obj 
    # enum.inject(sym)   => obj 
    # enum.inject(initial) {| memo, obj | block } => obj 
    # enum.inject   {| memo, obj | block } => obj 

我们的情况是第二个。

您也可以与传统的块重写:

op = :+ # parameter of inject call 
[1,2,3,4,5,6,7].inject {|sum, x| sum.send(op, x)} # also returns 28 

(回答“它是如何工作”的一部分)

+0

在这里找不到符号参数的信息,http://ruby-doc.org/core/classes/Enumerable.html。文档太旧了...... – 2010-08-11 06:10:41

+0

@Zifei这是1.8.6版的链接。查看http://ruby-doc.org/以获取其他版本的链接,核心API部分 – 2010-08-11 06:13:07

+1

获取它,http://ruby-doc.org/core-1.8.7/classes/Enumerable.html。谢谢。 – 2010-08-11 06:16:59

1

正如你可以看到in the docsinject可以采取块(像你”熟悉)或代表二元运算符名称的符号。这对已经定义的操作很有用。

+1

谢谢,红宝石1.9很甜蜜:) – 2010-08-11 06:13:42

3

:+是代表添加消息的symbol。请记住,Ruby具有Smalltalk风格,其中几乎每个操作都是通过向对象发送消息来执行的。

正如前面详细讨论的,here,(1..100).inject(&:+)是早期版本中的有效语法,其中Rails已将to_proc扩展添加到Symbol。

1.9和backported into 1.8.7中新增了将符号传入注入的功能。

+0

事实上,这种技术被称为“(着名的)符号>>价值:破解”(http://blog.3plus4.org/2007/03/27/selectors-as -blocks /)在Smalltalk社区中:'(1..100)reduce:#+' – 2011-11-24 11:47:22