Was ist der Unterschied zwischen dem Auslösen von Ausnahmen und dem Auslösen von Ausnahmen in Ruby?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ruby verfügt über zwei verschiedene Ausnahmemechanismen:Werfen/Fangen und Heben/Retten.

Warum haben wir zwei?

Wann sollten Sie das eine verwenden und das andere nicht?

War es hilfreich?

Lösung

Ich finde http://hasno.info/ruby-gotchas-and-caveats hat eine gute Erklärung für den Unterschied:

Fangen/Werfen ist nicht dasselbe wie Erhöhen/Retten.Mit Catch/Throw können Sie Blöcke schnell bis zu einem Punkt verlassen, an dem ein Catch für ein bestimmtes Symbol definiert ist. Raise Rescue ist die eigentliche Ausnahmebehandlung, die das Exception-Objekt betrifft.

Andere Tipps

  • raise, fail, rescue, Und ensure handhaben Fehler, auch bekannt als Ausnahmen
  • throw Und catch Sind Kontrollfluss

Im Gegensatz zu anderen Sprachen werden Rubys Wurf und Fang nicht für Ausnahmen verwendet.Stattdessen bieten sie eine Möglichkeit, die Ausführung frühzeitig zu beenden, wenn keine weiteren Arbeiten erforderlich sind.(Grimm, 2011)

Beenden einer einzelnen Ebene des Kontrollflusses, z. B while Schleife, kann mit einem einfachen durchgeführt werden return.Das Beenden vieler Ebenen des Kontrollflusses, wie z. B. einer verschachtelten Schleife, ist möglich throw.

Während sich der Ausnahmemechanismus „Raise and Rescue“ hervorragend eignet, um die Ausführung abzubrechen, wenn etwas schiefgeht, ist es manchmal schön, während der normalen Verarbeitung aus einem tief verschachtelten Konstrukt herausspringen zu können.Hier kommen Fangen und Werfen zum Einsatz.(Thomas und Hunt, 2001)

Verweise

  1. Grimm, Avdi."Wirf, fangen, heben, retten ... ich bin so verwirrt!" Rubylearning -Blog.N.p., 11. Juli 2011.Netz.1. Jan.2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. Thomas, Dave und Andrew Hunt."Rubin programmieren." :Der Leitfaden für pragmatische Programmierer.N.p., 2001.Netz.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 bietet eine hervorragende Erklärung, von der ich bezweifle, dass ich sie verbessern kann.Um es zusammenzufassen: Ich klaue im Laufe der Zeit einige Codebeispiele aus dem Blog-Beitrag:

  1. raise/rescue sind die nächsten Analoga zum throw/catch Konstrukt, mit dem Sie aus anderen Sprachen (oder dem von Python) vertraut sind raise/except).Wenn bei Ihnen eine Fehlerbedingung aufgetreten ist und Sie dies tun würden throw darüber in einer anderen Sprache schreiben, sollten Sie raise in Ruby.

  2. Rubys throw/catch ermöglicht es Ihnen, die Ausführung zu unterbrechen und den Stapel hinaufzuklettern, um nach einem zu suchen catch (wie raise/rescue tut), ist aber nicht wirklich für Fehlerbedingungen gedacht.Es sollte selten verwendet werden und dient nur dann, wenn Sie den Stapel hinaufgehen, bis Sie ein entsprechendes finden catch„Verhalten ist für einen Algorithmus, den Sie schreiben, sinnvoll, aber es wäre nicht sinnvoll, darüber nachzudenken throw als einem Fehlerzustand entsprechend.

    Wofür wird Fangen und Werfen in Ruby verwendet? bietet einige Vorschläge für schöne Verwendungsmöglichkeiten des throw/catch bauen.

Zu den konkreten Verhaltensunterschieden zwischen ihnen gehören:

  • rescue Foo wird Instanzen von retten Foo einschließlich Unterklassen von Foo. catch(foo) wird nur fangen das gleiche Objekt, Foo.Man kann nicht nur nicht bestehen catch einen Klassennamen, um Instanzen davon abzufangen, aber es werden nicht einmal Gleichheitsvergleiche durchgeführt.Zum Beispiel

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

    werde dir eine geben UncaughtThrowError: uncaught throw "foo" (oder ein ArgumentError in Ruby-Versionen vor 2.2)

  • Es können mehrere Rettungsklauseln aufgeführt werden...

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

    während mehrere catchEs muss verschachtelt werden...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • Ein nackter rescue ist äquivalent zu rescue StandardError und ist ein idiomatisches Konstrukt.Ein nackter catch", wie catch() {throw :foo}, wird niemals etwas fangen und sollte nicht verwendet werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top