红宝石块并从块中返回一些东西

Nic*_*ilt 5 ruby

我使用的是ruby 1.8.7.

p = lambda { return 10;}
def lab(block)
  puts 'before'
  puts block.call
  puts 'after'
end
lab p
Run Code Online (Sandbox Code Playgroud)

上面的代码输出是

before
10
after
Run Code Online (Sandbox Code Playgroud)

我重构了相同的代码

def lab(&block)
  puts 'before'
  puts block.call
  puts 'after'
end
lab { return 10; }
Run Code Online (Sandbox Code Playgroud)

现在我得到LocalJumpError:意外返回.

对我来说,代码都在做同样的事情.是的,在第一种情况下,我通过了一个过程,在第二种情况下,我正在通过一个块.但是阻止转换阻止进入proc.因此proc.call应该表现相同.

是的,我已经看过这篇文章在Ruby块中使用'return'

小智 8

当您使用&传入块时,您将其转换为proc.重要的一点是proc和lambda是不同的(lambda实际上是proc的子类),特别是它们如何处理return.

所以你的重构代码实际上相当于:

p = Proc.new { return 10;}
def lab(block)
  puts 'before'
  puts block.call
  puts 'after'
end
lab p
Run Code Online (Sandbox Code Playgroud)

这也会生成LocalJumpError.

原因如下:proc的返回从其词法范围返回,但lambda返回其执行范围.因此,当lambda返回时lab,传递给它的proc返回到声明它的外部作用域.本地跳转错误意味着无处可去,因为没有封闭功能.

Ruby Programming Language最好说:

Proc具有类似块的行为,lambdas具有类似方法的行为

你只需要跟踪你在哪里使用.正如其他人所建议的那样,你需要做的只是return从你的块中删除,事情将按预期工作.


sep*_*p2k 5

return块内部将从块所在的方法返回,而不是从块中返回.从块使用返回next(它的命名方式,因为使用迭代器方法eachmap从块返回基本上意味着跳转到循环的下一个迭代).

请注意,当返回值是块中最后一个求值表达式时,根本不需要任何类型的return语句,lab { 10 }即将执行相同的操作.