返回内部for循环内部lambda在Ruby 1.8中崩溃

时间:2009-07-05 07:07:40

标签: ruby lambda for-loop return

在Ruby 1.8(我的版本是1.8.7-72)中,这段代码:

foo = lambda do
  for j in 1..2
    return
  end
end
foo.call

LocalJumpError

崩溃
test2.rb:3: unexpected return (LocalJumpError)
    from test2.rb:2:in `each'
    from test2.rb:2
    from test2.rb:6:in `call'
    from test2.rb:6

为什么这样做?但是,它似乎在我的Ruby 1.9版本上运行良好。

编辑:这不仅仅是在lambda内部返回;运行良好:

foo = lambda do
  return
end
foo.call

2 个答案:

答案 0 :(得分:8)

正在发生的事情是lambda中间的for语句被内部转换为块。在Ruby中,块内的返回语句的作用域是它们的封闭方法。请考虑以下事项:

def bar
  foo = lambda do
    for j in 1..2
      return j
    end
  end
  foo[]
end
p bar

运行bar时,会返回1,因为return的范围限定为整个bar方法。要从块返回,您需要使用nextbreak,两者都需要参数。考虑:

def bar
  foo = lambda do
    for j in 1..2
      break j
    end
  end
  foo[] + 1
end
p bar

此中断会从块返回,并阻止任何后续迭代。在这种情况下,调用bar将返回2,因为迭代器将返回1,因此foo[] + 1将返回2

如果所有这些都让人感到困惑,那么要认识到的主要内容是将块内部的返回范围限定为周围的方法,如果没有周围的方法,则会引发LocalJumpError

答案 1 :(得分:0)

你可以使用throw / catch

来转义循环和lambda的其余部分
foo = lambda do 
        catch(:escape) do
          for j in 1..2
            throw :escape
          end
          # other code that won't get run
        end # catch(:escape)
      end # lambda

throw还有一个可选的第二个参数,您可以使用它来返回值。