2013-07-23 34 views
31

这个Ruby 2.0代码有什么问题?意外的回报(LocalJumpError)

p (1..8).collect{|denom| 
    (1...denom).collect{|num| 
     r = Rational(num, denom) 
     if r > Rational(1, 3) and r < Rational(1, 2) 
      return 1 
     else 
      return 0 
     end 
    } 
}.flatten 

错误出现在block (2 levels) in <main>': unexpected return (LocalJumpError)。我想创建一个包含n的平板列表(其余为零),其中n是分母低于8的有理数的数目,介于1/3和1/2之间。 (it's a Project Euler problem)。所以我试图从内部块返回。

+2

不要在块中使用'return'。只要删除'return',你的代码就可以了。 – oldergod

回答

37

您不能return在Ruby *的块内。最后一条语句成为返回值,所以你可以删除你的情况return语句:

p (1..8).collect{|denom| 
    (1...denom).collect{|num| 
     r = Rational(num, denom) 
     if r > Rational(1, 3) and r < Rational(1, 2) 
      1 
     else 
      0 
     end 
    } 
}.flatten 

*:你可以在里面lambda块:lambda { return "foo" }.call # => "foo"。它涉及范围界定和所有这些,这是lambda区块和proc区块之间的主要区别之一。您传递给方法的“正常”块更像proc块。

+55

您可以*在Ruby中使用'return'。它将从封闭的方法返回。在这种情况下,*没有*封闭方法,*这是*为什么会出现错误,它不是*,因为块中的“return”是非法的。 –

+0

@JörgWMittag你说得对,我正在简化。 'return'返回最近的方法*或*'lambda'块,你在里面。如果你不在里面,你会得到一个'LocalJumpError'。 – henrikhodne

+0

@JörgWMittag谢谢你的澄清声明。答案让人困惑,你澄清了它。我现在明白为什么这个错误很容易出现在irb中。 –