type - ruby rescue syntax




Quelle est la différence entre lever des exceptions et jeter des exceptions dans Ruby? (2)

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

catch / throw ne sont pas les mêmes que raise / rescue. catch / throw vous permet de quitter rapidement les blocs à un point où une capture est définie pour un symbole spécifique, raise rescue est la manipulation des exceptions réelles impliquant l'objet Exception.

Ruby a deux mécanismes d'exceptions différents: Lancer / Attraper et Raisonner / Secourir.

Pourquoi en avons-nous deux?

Quand devriez-vous en utiliser un et pas l'autre?


https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise offre une excellente explication que je doute que je puisse améliorer. Pour récapituler, en cliquant sur quelques exemples de code du blog, je vais:

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

  2. Le throw / catch de Ruby vous permet de casser l'exécution et de grimper sur la pile à la recherche d'un catch (comme le fait d' raise / de raise rescue ), mais n'est pas vraiment destiné aux conditions d'erreur. Il devrait être utilisé rarement, et est là juste pour quand le "remonter la pile jusqu'à ce que vous trouviez un catch correspondant" le comportement a un sens pour un algorithme que vous écrivez, mais il ne serait pas logique de penser que le throw correspond à une condition d'erreur.

    A quoi sert le catch et le lancer dans Ruby? offre quelques suggestions sur les bonnes utilisations de la construction throw / catch .

Les différences de comportement concrètes entre eux comprennent:

  • rescue Foo va sauver des instances de Foo incluant des sous-classes de Foo . catch(foo) n'attrapera que le même objet, Foo . Non seulement vous ne pouvez pas passer un nom de classe pour en attraper des instances, mais il ne fera même pas de comparaison d'égalité. Par exemple

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

    vous donnera un UncaughtThrowError: uncaught throw "foo" (ou une ArgumentError dans les versions de Ruby avant 2.2)

  • Plusieurs clauses de secours peuvent être listées ...

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

    alors que les catch multiples doivent être imbriquées ...

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







exception