Ruby Lambda 与 Proc LocalJumpError

Tim*_*sey 4 ruby proc-object

Ruby 和 StackOverflow 新手在这里使用 Ruby 进行工作,并遇到了我的第一个主要障碍。我真的很难理解 Procs 和 Lambdas。这是我正在使用的代码。

def procBuilder(message)
  Proc.new{ puts message; return}
end

def test
  puts "entering method"
  p = procBuilder("entering proc")
  p.call
  puts "exit method"
end

test
Run Code Online (Sandbox Code Playgroud)

按照设计,这是为了抛出 LocalJumpError,但我不明白为什么。如果我不得不猜测这是做什么的,我猜它最初会在 p = procBuilder("entering proc") 运行时打印“entering proc”,然后在 p.call 上抛出错误,因为 p.call 没有传递任何字符串,但显然我错过了这两行之间发生的一些关键事情。我也不完全理解为什么这适用于 lambda 而不是 proc,但我想理解错误也能解决该问题。

预先感谢您的澄清

小智 5

这是我对相关问题的回答。它讨论了一些关于 lambda 与 proc 和 LocalJumpErrors 的内容。

在 proc 中,return是一段特殊的语法,它从proc 的词法范围返回,而不是从 proc 本身返回。所以它试图从procBuilder已经退出的 中返回。

有几种方法可以解决这个问题:

  1. return根本不要使用。Ruby 将自行将控制权返回给 proc 的调用者。
  2. 更改proclambda,其行为符合您的预期。Lambda 的行为类似于方法;过程就像块一样。

至于您所期望的错误,您不应该得到它。procBuilder返回包含消息变量的过程。您不需要过程本身的任何参数。

编辑:回答您的附加问题。该过程是一个闭包。它“捕获”了消息变量( 中的局部变量procBuilder),该变量在创建过程时就在范围内。现在,proc 可以在您的程序中徘徊,消息变量隐藏在其中,准备在您调用它时打印。唯一的麻烦是 return 语句,它有一个额外的要求,即词法范围仍然是“活动的”。

这一切的原因是这种行为在块中确实很有帮助。在这种情况下,它根本没有帮助,所以你应该只使用 a lambda,其中 return 意味着不那么疯狂的事情。

关于 ruby​​ 中闭包的非常好的教程:http://innig.net/software/ruby/closures-in-ruby.rb