Wie kann ich etwas frühzeitig von einem Block zurückgeben?

88

Wenn ich so etwas machen wollte:

collection.each do |i|
   return nil if i == 3

   ..many lines of code here..
end

Wie würde ich diesen Effekt erzielen? Ich weiß, ich könnte einfach alles in den Block in eine große if-Anweisung einschließen, aber ich möchte die Verschachtelung nach Möglichkeit vermeiden.

Break würde hier nicht funktionieren, da ich die Iteration der verbleibenden Elemente nicht stoppen möchte.

Ryeguy
quelle

Antworten:

173

nextinnerhalb eines Blocks kehrt aus dem Block zurück. breakinnerhalb eines Blocks kehrt von der Funktion zurück, die dem Block nachgegeben hat. Für eachdas bedeutet , dass breakdie Schleife und beendet nextspringt in der nächsten Iteration der Schleife (also die Namen). Sie können Werte mit next valueund zurückgeben break value.

sepp2k
quelle
51
+1 für das next valueund break value. Genau das, wonach ich gesucht habe.
Joshua Pinter
1
break valuehat bei mir nicht funktioniert, hat aber gut next valuefunktioniert. Vielen Dank.
Francesco Belladonna
4
Ich bin mir nicht sicher, ob Ihre Definition von next und break korrekt ist. Zumindest sind sie verwirrend. break verlässt die innerste Schleife und bringt Sie zur nächsten Iteration. Quelle: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox
3
@WattsInABox nextund breaksind in keiner Weise spezifisch für Schleifenkonstrukte, daher ist der Artikel, den Sie verlinkt haben, sehr irreführend (da er stark das Gegenteil impliziert). Und meine Beschreibungen sind definitiv korrekt, wenn nextund breakinnerhalb von Blöcken verwendet werden (beachten Sie, dass whileund forwerden selten, wenn überhaupt, in Ruby verwendet, so dass 99% der Verwendungen von nextund breakinnerhalb von Blöcken liegen).
sepp2k
Ich denke du meinst nicht schleifende Blöcke. Das ist das Verwirrende daran. Ich bin auch nicht mit Ihrer 99% igen Behauptung einverstanden, aber das ist ein anderes Argument.
WattsInABox
11
#!/usr/bin/ruby

collection = [1, 2, 3, 4, 5 ]

stopped_at = collection.each do |i|
   break i if i == 3

   puts "Processed #{i}"
end

puts "Stopped at and did not process #{stopped_at}"
JD.
quelle
5

In diesem Fall können Sie break verwenden, um die Schleife vorzeitig zu beenden:

collection.each do |i|
  break if i == 3
  ...many lines
end

... dies setzt natürlich voraus, dass Sie nicht wirklich einen Wert zurückgeben möchten, sondern nur aus dem Block ausbrechen.

Sniggerfardimungus
quelle
Dies würde nicht nur vom Block zurückkehren, sondern von jedem. Die Schleife würde also enden und nicht mit dem nächsten Wert fortfahren. Ich bin mir nicht sicher, ob das beabsichtigt ist.
sepp2k
3
Sie können einen Wert mit breakin Ruby verwenden - break 5führt dazu each, dass 5 zurückgegeben wird.
Chuck
1
Danke, aber ich möchte die Iteration nicht stoppen.
Ryeguy