Quelle est la différence entre lever des exceptions et lancer des exceptions dans Ruby ?

StackOverflow https://stackoverflow.com/questions/51021

  •  09-06-2019
  •  | 
  •  

Question

Ruby a deux mécanismes d'exceptions différents :Lancer/attraper et relancer/sauvetage.

Pourquoi en avons-nous deux ?

Quand faut-il utiliser l’un et pas l’autre ?

Était-ce utile?

La solution

Je pense http://hasno.info/ruby-gotchas-and-caveats a une explication décente de la différence:

attraper/lancer ne sont pas la même chose que relancer/sauvetage.catch/throw vous permet de quitter rapidement les blocs jusqu'à un point où un catch est défini pour un symbole spécifique, raise Rescue est le véritable élément de gestion des exceptions impliquant l'objet Exception.

Autres conseils

  • raise, fail, rescue, et ensure poignée les erreurs, aussi connu sous le nom des exceptions
  • throw et catch sont flux de contrôle

Contrairement à d'autres langues, le lancer et les captures de Ruby ne sont pas utilisés pour des exceptions.Au lieu de cela, ils fournissent un moyen de mettre fin à l'exécution tôt lorsqu'aucun autre travail n'est nécessaire.(Grimm, 2011)

Terminer un seul niveau de flux de contrôle, comme un while boucle, peut être fait avec un simple return.La terminaison de plusieurs niveaux de flux de contrôle, comme une boucle imbriquée, peut être effectuée avec throw.

Bien que le mécanisme d'exception de relance et de sauvetage soit idéal pour abandonner l'exécution lorsque les choses tournent mal, il est parfois agréable de pouvoir sortir d'une construction profondément imbriquée pendant un traitement normal.C’est là que attraper et lancer s’avère utile.(Thomas et Hunt, 2001)

Les références

  1. Grimm, Avdi."Jetez, attrapez, soulevez, sauvez ... je suis tellement confus!" Blog RubyLearning.N.p., 11 juillet 2011.La toile.1er janvier2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. Thomas, Dave et Andrew Hunt."Programmation Ruby." :Le guide du programmeur pragmatique.N.p., 2001.La toile.29 sept.2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html.

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise offre une excellente explication que je doute de pouvoir améliorer.Pour résumer, en reprenant quelques exemples de code du billet de blog au fur et à mesure :

  1. raise/rescue sont les analogues les plus proches du throw/catch construction que vous connaissez dans d'autres langages (ou dans Python raise/except).Si vous avez rencontré une condition d'erreur et que vous throw dessus dans une autre langue, vous devriez raise en Rubis.

  2. chez Ruby throw/catch vous permet d'interrompre l'exécution et de gravir la pile à la recherche d'un catch (comme raise/rescue le fait), mais n'est pas vraiment destiné aux conditions d'erreur.Il devrait être utilisé rarement, et n'est-il là que lorsque "montez la pile jusqu'à ce que vous trouviez un correspondant catch" le comportement a du sens pour un algorithme que vous écrivez, mais cela n'aurait aucun sens de penser au throw comme correspondant à une condition d’erreur.

    À quoi servent le catch and throw dans Ruby ? propose quelques suggestions sur des utilisations intéressantes du throw/catch construction.

Les différences comportementales concrètes entre eux comprennent :

  • rescue Foo sauvera des cas de Foo y compris les sous-classes de Foo. catch(foo) ne fera qu'attraper le même objet, Foo.Non seulement tu ne peux pas passer catch un nom de classe pour en détecter les instances, mais il ne fera même pas de comparaisons d'égalité.Par exemple

    catch("foo") do
      throw "foo"
    end
    

    vous donnera un UncaughtThrowError: uncaught throw "foo" (ou un ArgumentError dans les versions de Ruby antérieures à 2.2)

  • Plusieurs clauses de sauvetage peuvent être répertoriées...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end
    

    alors que plusieurs catchil faut les imbriquer...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • Un nu rescue est équivalent à rescue StandardError et est une construction idiomatique.Un nu catch", comme catch() {throw :foo}, n'attrapera jamais rien et ne devrait pas être utilisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top