259 votes

Comment revenir plus tôt d'une tâche de ratissage ?

J'ai une tâche rake dans laquelle je fais quelques vérifications au début, si l'une des vérifications échoue, je voudrais revenir plus tôt de la tâche rake, je ne veux pas exécuter le code restant.

Je pensais que la solution serait de placer un retour à l'endroit où je voulais retourner du code mais j'obtiens l'erreur suivante

unexpected return

334voto

Simone Carletti Points 77653

Une tâche Rake est fondamentalement un bloc. Un bloc, à l'exception des lambdas, ne supporte pas le retour mais vous pouvez passer à l'instruction suivante en utilisant next ce qui dans une tâche rake a le même effet que d'utiliser return dans une méthode.

task :foo do
  puts "printed"
  next
  puts "never printed"
end

Ou vous pouvez déplacer le code dans une méthode et utiliser le retour dans la méthode.

task :foo do
  do_something
end

def do_something
  puts "startd"
  return
  puts "end"
end

Je préfère le deuxième choix.

21 votes

J'aime aussi le deuxième. Plus j'utilise rake, plus j'aime garder le code non trivial en dehors de la définition de la tâche. Ce n'est pas une règle ferme à 100%, mais cela semble être une bonne ligne directrice pour travailler.

0 votes

Je suis tout à fait d'accord. De plus, les méthodes sont beaucoup plus faciles à tester.

2 votes

La deuxième solution est plus agréable. Dans votre première solution, je préférerais utiliser break au lieu de next pour sortir du bloc... Ça devrait marcher aussi, non ?

205voto

Sergikon Points 571

Vous pouvez utiliser abort(message) depuis l'intérieur de la tâche pour interrompre cette tâche avec un message.

5 votes

@TylerRick Non, c'est Noyau#abandon .

10 votes

Cette méthode est supérieure pour sortir dans les situations de non-réussite, car elle définit automatiquement le statut de sortie.

0 votes

C'est une victoire. C'est aussi un moyen facile de fournir un retour d'information sur l'utilisation des erreurs d'argumentation.

45voto

Josh Pinter Points 3814

Retour avec une erreur ❌

Si vous revenez avec une erreur (c'est-à-dire un code de sortie de 1 ), vous voudrez utiliser abort qui prend également une chaîne de caractères optionnelle qui sera affichée à la sortie :

task :check do

  # If any of your checks fail, you can exit early like this.
  abort( "One of the checks has failed!" ) if check_failed?

end

Sur la ligne de commande :

$ rake check && echo "All good"
#=> One of the checks has failed!

Retour avec succès ✅

Si vous revenez sans une erreur (c'est-à-dire un code de sortie de 0 ), vous voudrez utiliser exit qui n'est pas prend un paramètre de type chaîne.

task :check do

  # If any of your checks fail, you can exit early like this.
  exit if check_failed?

end

Sur la ligne de commande :

$ rake check && echo "All good"
#=> All good

C'est important si vous l'utilisez dans une tâche cron ou quelque chose qui doit faire quelque chose par la suite en fonction de la réussite ou non de la tâche rake.


Bonus : Retour avec une erreur à partir d'un rescue sans la trace de la pile.

Par défaut, si vous utilisez abort à l'intérieur d'un rescue il affichera l'intégralité de la trace de la pile, même si vous n'utilisez que le bloc abort sans relancer l'erreur.

Pour contourner ce problème, vous pouvez fournir un code de sortie non nul à la fonction exit comme :

task :check do

  begin
    do_the_thing_that_raises_an_exception
  rescue => error
    puts error.message

    exit( 1 )
  end

end

23voto

khelll Points 12222

J'ai tendance à utiliser abort qui est une meilleure alternative dans de telles situations, par exemple :

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end

13voto

mjs Points 9378

Si vous avez besoin de sortir de multiple les niveaux de blocs, vous pouvez utiliser échouer .

Par exemple

task :something do
  [1,2,3].each do |i|
    ...
    fail "some error" if ...
  end
end

(Voir https://stackoverflow.com/a/3753955/11543 .)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X