Trouble yielding inside a block/lambda

无人久伴 提交于 2019-11-28 13:31:22

Lambdas don't implicitly accept blocks like regular methods do, so your func1 can't yield. Do this instead:

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

Specifically, I believe this is because yield would send control back to the caller's block, which would not include lambda invocations. So the following code works like you "expect":

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

In Ruby 1.9 only:

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))

Based upon Nikita Misharin's answer here:[https://stackoverflow.com/a/45571976/2165560], I like this:

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 }

It answers my question here [In Ruby, can you use the lambda or or Proc call method to invoke an iterator?.

By wrapping the iterator it can be arbitrarily passed to other methods and iterate on their blocks.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!