Comment puis-je retourner quelque chose plus tôt d'un bloc?

91

Si je voulais faire quelque chose comme ça:

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

   ..many lines of code here..
end

Comment pourrais-je obtenir cet effet? Je sais que je pourrais simplement tout envelopper à l'intérieur du bloc dans une grande déclaration if, mais j'aimerais éviter l'imbrication si possible.

Pause ne fonctionnerait pas ici, parce que je ne pas veux arrêter l' itération des éléments restants.

Ryeguy
la source

Réponses:

177

nextà l'intérieur d'un bloc revient du bloc. breakà l'intérieur d'un bloc renvoie de la fonction qui a cédé au bloc. Car eachcela signifie que breakquitte la boucle et nextpasse à l'itération suivante de la boucle (donc les noms). Vous pouvez renvoyer des valeurs avec next valueet break value.

sepp2k
la source
54
+1 pour le next valueet break value. Exactement ce que je cherchais.
Joshua Pinter
1
break valuen'a pas fonctionné pour moi, tout next valuea bien fonctionné. Merci beaucoup.
Francesco Belladonna
4
Je ne suis pas sûr que votre définition du prochain et de la pause soit correcte. À tout le moins, ils prêtent à confusion. break sort de la boucle la plus interne, ensuite vous déplace vers l'itération suivante. source: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox
3
@WattsInABox nextet ne breaksont en aucun cas spécifiques aux constructions en boucle, donc l'article que vous avez lié est très trompeur (car il implique fortement le contraire). Et mes descriptions sont définitivement correctes quand nextet breaksont utilisées à l'intérieur de blocs (notez que whileet forsont rarement, voire jamais, utilisées dans Ruby, donc 99% des utilisations de nextet breaksont dans des blocs).
sepp2k
Je pense que vous voulez dire des blocs sans boucle. C'est ce qui est déroutant à ce sujet. De plus, je ne suis pas d'accord avec votre affirmation à 99%, mais c'est un argument différent.
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.
la source
5

Dans cet exemple, vous pouvez utiliser break pour terminer la boucle prématurément:

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

... bien sûr, cela suppose que vous ne cherchez pas réellement à renvoyer une valeur, sortez simplement du bloc.

Sniggerfardimungus
la source
Cela ne reviendrait pas seulement du bloc, cela reviendrait de chacun. Ainsi, la boucle se terminerait, pas continuer avec la valeur suivante. Pas sûr que ce soit ce qui est prévu.
sepp2k
4
Vous pouvez utiliser une valeur avec breakdans Ruby - break 5provoquera eachle retour 5.
Chuck
1
Merci, mais je ne veux pas arrêter l'itération.
ryeguy