2013-07-23 11 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'とコードの両方を削除するだけでOKです。 – oldergod

答えて

37

Rubyのブロック内にreturnを入れることはできません*最後の文は、戻り値になるので、あなたは自分の場合は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ブロックの主な違いの1つです。メソッドに渡す "通常の"ブロックは、procのブロックによく似ています。

+55

Rubyではブロック内で 'return'を使用できます。それは囲む方法から戻るでしょう。この場合、*囲みメソッドはありません。*それは、ブロック内の 'return'が不正であるため、エラーが発生する理由です。 –

+0

@JörgWMittagあなたが正しいです、私は単純化していました。 'return'は内部にある最も近いメソッド*または*' lambda'ブロックを返します。あなたが内部にいなければ、 'LocalJumpError'を取得します。 – henrikhodne

+0

@JörgWMittagこの明確なステートメントのおかげで。答えは現状のままで混乱しており、あなたはそれを明確にしました。私は今なぜこのエラーがirbで簡単に現れるのか理解しています。 –

関連する問題