Come posso restituire qualcosa in anticipo da un blocco?


90

Se volessi fare qualcosa del genere:

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

   ..many lines of code here..
end

Come avrei ottenuto quell'effetto? So che potrei semplicemente avvolgere tutto all'interno del blocco in una grande istruzione if, ma vorrei evitare l'annidamento se possibile.

Break non funzionerebbe qui, perché non voglio interrompere l'iterazione degli elementi rimanenti.

Risposte:


176

nextall'interno di un blocco ritorna dal blocco. breakall'interno di un blocco ritorna dalla funzione che ha prodotto il blocco. Per eachquesto significa che breakesce dal ciclo e nextsalta alla successiva iterazione del ciclo (quindi i nomi). Puoi restituire valori con next valuee break value.


53
+1 per next valuee break value. Esattamente quello che stavo cercando.
Joshua Pinter

1
break valuenon ha funzionato per me, mentre ha next valuefunzionato bene. Molte grazie.
Francesco Belladonna

4
Non sono sicuro che la tua definizione di next e break sia corretta. Per lo meno, creano confusione. break esce dal loop più interno, next ti sposta alla successiva iterazione. fonte: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox

3
@ WattsInABox nexte non breaksono in alcun modo specifici per i costrutti di loop, quindi l'articolo che hai collegato è molto fuorviante (poiché implica fortemente il contrario). E le mie descrizioni sono decisamente corrette quando nexte breakvengono utilizzate all'interno dei blocchi (nota che whilee forsono usate raramente, se non mai, in Ruby, quindi il 99% degli usi nexte breaksono all'interno di blocchi).
sepp2k

Penso che tu intenda blocchi senza loop. Questo è ciò che confonde. Inoltre, non sono d'accordo con la tua affermazione del 99%, ma questo è un argomento diverso.
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

In questo caso, puoi usare break per terminare il ciclo in anticipo:

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

... ovviamente, si presume che non si stia effettivamente cercando di restituire un valore, ma semplicemente di uscire dal blocco.


Questo non tornerebbe solo dal blocco, ma tornerebbe da ciascuno. Quindi il ciclo finirà, non continuerà con il valore successivo. Non sono sicuro che sia quello che si intende.
sepp2k

4
Puoi usare un valore con breakin Ruby - break 5ne eachrestituirà 5.
Chuck

1
Grazie, ma non voglio interrompere l'iterazione.
Ryeguy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.