2013-07-23 8 views
31

Was ist das Problem mit diesem Ruby 2.0-Code?Unerwartete Rückgabe (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 

Der Fehler ist in block (2 levels) in <main>': unexpected return (LocalJumpError). Ich möchte eine flache Liste mit n Einsen (und den Rest Nullen) erstellen, wobei n die Anzahl der rationalen Zahlen mit Nennern unter 8 ist, die zwischen 1/3 und 1/2 sind. (it's a Project Euler problem). Also versuche ich aus dem inneren Block zurückzukehren.

+2

Verwenden Sie 'return' nicht in einem Block. Entfernen Sie einfach beide 'Return' und Ihr Code wird in Ordnung sein. – oldergod

Antwort

37

Sie können nicht return innerhalb eines Blocks in Ruby *. Die letzte Anweisung wird der Rückgabewert, so dass Sie nur die return-Anweisungen in Ihrem Fall entfernen:

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 

*: Sie können innerhalb lambda Blöcke: lambda { return "foo" }.call # => "foo". Es hat mit Scoping und all dem zu tun, und dies ist einer der Hauptunterschiede zwischen lambda Blöcke und proc Blöcke. "Normale" Blöcke, die Sie an Methoden übergeben, sind eher proc Blöcke.

+55

Sie können * return 'innerhalb eines Blocks in Ruby verwenden. Es wird von der umschließenden Methode zurückkehren. In diesem Fall gibt es * keine * einschließende Methode, * das ist * warum es einen Fehler gibt, es ist * nicht * weil "Rückkehr" in einem Block illegal ist. –

+0

@ JörgWMittag Du hast recht, ich habe mich vereinfacht. 'return' gibt die nächste Methode * oder *' lambda' zurück, in der Sie sich befinden. Wenn Sie nicht in einem sind, erhalten Sie einen 'LocalJumpError'. – henrikhodne

+0

@ JörgWMittag danke für diese klärende Aussage. Die Antwort war verwirrend wie es ist und du hast es geklärt. Ich verstehe jetzt, warum dieser Fehler in irb leicht auftritt. –