【问题标题】:Ruby: Yielding from an inner block does not workRuby:从内部块产生不起作用
【发布时间】:2016-05-22 22:36:39
【问题描述】:

我正在开发一个输出文本的 Ruby 项目,我希望在该项目中允许其他代码更改包装器的一部分。下面是一个简化的例子:

  • 输出的外包装由该项目生成
  • 内部包装由用户指定的代码生成
  • 在这个内部包装器中,调用yield 将使项目生成内部内容。

但是,我在尝试运行以下代码时遇到了一个非常奇怪的错误:

def wrapper(&block)
  puts "begin outer wrapper"
  block.call do
    puts "inner content"
  end
  puts "end outer wrapper"
end

wrapper do
  puts "begin inner wrapper"
  yield
  puts "end inner wrapper"
end

我希望得到以下输出:

begin outer wrapper
begin inner wrapper
inner content
end inner wrapper
end outer wrapper

这不会发生。相反,Ruby 会抛出以下错误:LocalJumpError: no block given (yield)

出了什么问题?

编辑:根据@JörgWMittag 的回答,这是确实 工作的变体:

def wrapper(&block)
  puts "begin outer wrapper"
  block.call do
    puts "inner content"
  end
  puts "end outer wrapper"
end

wrapper do |&inner_block|
  puts "begin inner wrapper"
  inner_block.call
  puts "end inner wrapper"
end

基本上,yieldProc#call() 毕竟是截然不同的野兽。

【问题讨论】:

    标签: ruby lambda yield proc


    【解决方案1】:

    出了什么问题?

    yield 将控制权转移到传递给在其定义中出现yield 的方法的块。在您的情况下,yield 没有出现在方法定义中,因此,yield 无处可去。

    【讨论】:

    • 谢谢!我花了一段时间才明白你的答案,但现在很清楚了。基本上,当我将块称为wrapper do 中的参数时,我可以毫无问题地对其进行#call。所以这段代码确实工作:def wrapper(&block) puts "begin outer wrapper" block.call do puts "inner content" end puts "end outer wrapper" end wrapper do |&passed_block| puts "begin inner wrapper" passed_block.call puts "end inner wrapper" end 看来,yield#call 并不像网络上的大多数解释让你相信的那样相似......
    猜你喜欢
    • 2010-12-08
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    相关资源
    最近更新 更多