Jak mogę wcześniej zwrócić coś z bloku?


91

Gdybym chciał zrobić coś takiego:

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

   ..many lines of code here..
end

Jak uzyskać taki efekt? Wiem, że mógłbym po prostu zawinąć wszystko wewnątrz bloku w duże wyrażenie if, ale chciałbym uniknąć zagnieżdżania, jeśli to możliwe.

Break nie zadziała tutaj, ponieważ nie chcę przerywać iteracji pozostałych elementów.

Odpowiedzi:


177

nextwewnątrz bloku wraca z bloku. breakwewnątrz bloku powraca z funkcji, która oddała blok. Na eachten oznacza, że breakwyjście z pętli i nextprzeskakuje do następnej iteracji pętli (stąd nazwy). Możesz zwracać wartości za pomocą next valuei break value.


54
+1 dla next valuei break value. Dokładnie to, czego szukałem.
Joshua Pinter

1
break valuenie działało dla mnie, ale next valuedziałało dobrze. Wielkie dzięki.
Francesco Belladonna

4
Nie jestem pewien, czy twoja definicja next i break jest poprawna. Przynajmniej są mylące. break opuszcza najgłębszą pętlę, next przenosi cię do następnej iteracji. źródło: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox,

3
@WattsInABox nexti nie breaksą w żaden sposób specyficzne dla konstrukcji zapętlonych, więc artykuł, który łączysz, jest bardzo mylący (ponieważ silnie sugeruje coś przeciwnego). I moje opisy są zdecydowanie poprawna, kiedy nexti breaksą używane wewnątrz bloków (zauważ, że whilei forsą rzadko, jeśli w ogóle, stosowany w Ruby więc 99% zastosowań nexti breaksą w blokach).
sepp2k

Myślę, że masz na myśli niepętlające się bloki. To właśnie jest w tym dezorientujące. Nie zgadzam się też z twoim stwierdzeniem o 99%, ale to inny 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}"

5

W tym przypadku możesz użyć break, aby wcześniej zakończyć pętlę:

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

... oczywiście przy założeniu, że tak naprawdę nie chcesz zwrócić wartości, po prostu wyrwij się z bloku.


To nie tylko powróci z bloku, ale wróci z każdego. Więc pętla zakończyłaby się, a nie kontynuowała z następną wartością. Nie jestem pewien, czy to jest zamierzone.
wrzesień

4
Możesz użyć wartości z breakw Rubim - break 5spowoduje eachzwrócenie 5.
Chuck

1
Dzięki, ale nie chcę przerywać iteracji.
ryeguy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.