¿Cómo puedo devolver algo antes de tiempo de un bloque?

90

Si quisiera hacer algo como esto:

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

   ..many lines of code here..
end

¿Cómo obtendría ese efecto? Sé que podría envolver todo dentro del bloque en una gran declaración if, pero me gustaría evitar el anidamiento si es posible.

Break no funcionaría aquí, porque no quiero detener la iteración de los elementos restantes.

centeno
fuente

Respuestas:

176

nextdentro de un bloque regresa del bloque. breakdentro de un bloque regresa de la función que cedió al bloque. Porque eachesto significa que breaksale del ciclo y nextsalta a la siguiente iteración del ciclo (de ahí los nombres). Puede devolver valores con next valuey break value.

sepp2k
fuente
53
+1 para next valuey break value. Exactamente lo que estaba buscando.
Joshua Pinter
1
break valueno funcionó para mí, aunque next valuefuncionó bien. Muchas gracias.
Francesco Belladonna
4
No estoy seguro de que su definición de next y break sea correcta. Por lo menos, son confusos. break sale del bucle más interno, luego lo mueve a la siguiente iteración. fuente: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox
3
@WattsInABox nexty breakde ninguna manera son específicos de las construcciones de bucle, por lo que el artículo que vinculó es muy engañoso (ya que implica en gran medida lo contrario). Y mis descripciones son definitivamente correctas cuando nexty breakse usan dentro de bloques (tenga en cuenta que whiley forrara vez, si alguna vez, se usan en Ruby, por lo que el 99% de los usos de nexty breakestán dentro de bloques).
sepp2k
Creo que te refieres a bloques sin bucle. Eso es lo que confunde. Además, no estoy de acuerdo con su afirmación del 99%, pero ese es un argumento diferente.
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.
fuente
5

En este caso, puede usar break para terminar el ciclo antes:

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

... por supuesto, esto supone que en realidad no está buscando devolver un valor, simplemente salga del bloque.

Sniggerfardimungus
fuente
Esto no solo volvería del bloque, volvería de cada uno. Entonces el ciclo terminaría, no continuaría con el siguiente valor. No estoy seguro de que eso sea lo que se pretende.
sepp2k
4
Puede usar un valor con breaken Ruby - break 5hará eachque se devuelva 5.
Chuck
1
Gracias, pero no quiero detener la iteración.
ryeguy