在块/ lambda中产生麻烦

我有以下Ruby代码:

# func1 generates a sequence of items derived from x # func2 does something with the items generated by func1 def test(x, func1, func2) func1.call(x) do | y | func2.call(y) end end func1 = lambda do | x | for i in 1 .. 5 yield x * i end end func2 = lambda do | y | puts y end test(2, func1, func2) # Should print '2', '4', '6', '8', and '10' 

当然,这不起作用。

 test.rb:11: no block given (LocalJumpError) from test.rb:10:in `each' from test.rb:10 from test.rb:4:in `call' from test.rb:4:in `test' from test.rb:20 

Lambdas不会像常规方法那样隐式接受块,所以你的func1不能产生。 改为:

 func1 = lambda do |x, &blk| for i in 1 .. 5 blk.call(x * i) end end 

具体来说,我认为这是因为yield会将控制权发送回caller的块,这不包括lambda调用。 所以下面的代码就像你“期待”一样:

 def foo (lambda { |n| yield(n) }).call(5) end foo { |f| puts f } # prints 5 

仅在Ruby 1.9中:

 func1 = lambda do |x, &blk| for i in 1..5 blk.call(x*i) end end 
 def test(x, func1, func2) func1.call(x) do | y | func2.call(y) end end #change func1 to a method def func1 x for i in 1 .. 5 yield x * i end end #func2 may be either a method or a lambda #I changed it for consistency, but you don't have to def func2 y puts y end test(2, method(:func1), method(:func2)) 

基于Nikita Misharin的回答:[ https://stackoverflow.com/a/45571976/2165560%5D ,我喜欢这个:

 def iterator(x) for i in 1 .. 5 yield x * i end end iteratorWrapper = -> (m,&block) { iterator(m) {|n| block.call n} } iteratorWrapper.call(2) { |y| puts y } 

它在这里回答了我的问题[ 在Ruby中,你可以使用lambda或proc调用方法来调用迭代器吗? 。

通过包装迭代器,它可以任意传递给其他方法并迭代它们的块。