2

在 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
4

2 回答 2

8

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

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

运行时bar1返回,因为它return的作用域是整个bar方法。要从块中返回,您需要使用nextor break,两者都带有参数。考虑:

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

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

如果所有这些听起来令人困惑,那么要意识到的主要事情是,块内的 return 被限定为一个周围的方法,如果没有一个周围的方法,LocalJumpError就会引发 a。

于 2009-07-05T07:20:02.397 回答
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还需要一个可选的第二个参数,您可以使用它来返回一个值。

于 2009-07-05T15:23:55.477 回答