传递一个lambda作为一个块

我试图定义一个块,我将使用传递多个范围的每个方法。 而不是重新定义每个范围的块,我想创build一个lamba,并传递lambda:

count = 0 procedure = lambda {|v| map[count+=1]=v} ("A".."K").each procedure ("M".."N").each procedure ("P".."Z").each procedure 

但是,我得到以下错误:

 ArgumentError:错误的参数个数(1代表0)
    来自code.rb:23:在“每个”

任何想法发生了什么?

将&符号( & )加到参数上,例如:

 ("A".."K").each &procedure 

这表示您将它作为方法的特殊块parameter passing。 否则,它被解释为一个正常的论点。

它也反映了它们在方法本身内部捕获和访问块参数的方式:

 # the & here signifies that the special block parameter should be captured # into the variable `procedure` def some_func(foo, bar, &procedure) procedure.call(foo, bar) end some_func(2, 3) {|a, b| a * b } => 6 

诀窍在于,如果需要,使用&告诉Ruby将此参数转换为Proc ,然后使用该对象作为方法的块。 从Ruby 1.9开始,有一个lambda(匿名)函数的快捷方式。 所以,你可以写这样的代码:

 (1..5).map &->(x){ x*x } # => [1, 4, 9, 16, 25] 

将采取arrays的每个元素并且计算它的力量

它和这个代码一样:

 func = ->(x) { x*x } (1..5).map &func 

对于Ruby 1.8:

 (1..5).map &lambda {|x| x*x} # => [1, 4, 9, 16, 25] 

为了解决你的问题,你可以使用Array的方法reduce0是初始值):

 ('A'..'K').reduce(0) { |sum,elem| sum + elem.size } # => 11 

传递一个lambda函数来reduce有点棘手,但是匿名块和lambda几乎是一样的。

 ('A'..'K').reduce(0) { |sum, elem| ->(sum){ sum + 1}.call(sum) } # => 11 

或者你可以像这样连接字母:

 ('A'..'K').reduce(:+) => "ABCDEFGHIJK" 

转换为小写:

 ('A'..'K').map &->(a){ a.downcase } => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"] 

在方法定义的上下文中,在最后一个参数前加一个“&”符号表示一个方法可能会占用一个块,并给我们一个名称来引用方法体内的这个块。