2012-11-20 9 views
5

catch in Ruby soll aus tief verschachtelten Code springen. In Java z.B. Es ist möglich, dasselbe mit Javas try-catch zu erreichen, das für die Behandlung von Ausnahmen gedacht ist, es wird jedoch als schlechte Lösung angesehen und ist auch sehr ineffizient. In Ruby für die Behandlung von Ausnahmen haben wir begin-raise-rescue und ich nehme an, es ist auch zu teuer, es für andere Aufgaben zu verwenden.Ruby Catch-Throw und Effizienz

Ist Rubys catch-throw wirklich eine effizientere Lösung als begin-raise-rescue oder gibt es andere Gründe, es zu verwenden, um verschachtelte Blöcke anstelle von begin-raise-rescue zu brechen?

+0

Wenn Sie einige Ruby-Beispiele der Kontrollstrukturen posten, nach denen Sie fragen, kann es klarer sein, was Sie meinen. –

Antwort

5

Neben der "richtigen" Möglichkeit, außer Kontrolle Strukturen zu bekommen, ist catch-throw auch deutlich schneller (10 mal so schnell in meiner Prüfung). Check out this gist für meinen Code und Ergebnisse.

+0

+1 für das Benchmarking. – steenslag

+0

Danke! Die Benchmark löst das Problem (in meinem Fall sind es fast 15 Mal!). Sollte Fangwurf als ein strukturierter Programmierstil angesehen werden - eine bessere Übung, als verachtet zu werden? – wrzasa

+0

Es ist Ihr Design erfordert Fangwurf, es gibt wahrscheinlich ein besseres Design. Abgesehen davon gibt es definitiv Randfälle, in denen Fangwurf sehr sinnvoll ist, vor allem in Edelstein-Entwicklung, wo Sie nicht wissen, wie der Endnutzer es verwenden wird. – Josh

5

Josh's answer ist korrekt. Ich möchte mehr Informationen über catch-throw und raise-rescue hinzufügen.

catch-throw wird für die Flusssteuerung verwendet, während raise-rescue für die Ausnahme/Fehlerbehandlung verwendet wird. Der Unterschied ist: backtrace wird nicht benötigt für catch-throw (Flusskontrolle). Vertrauen Sie mir, der Hauptgrund verursacht raise-rescue läuft langsam als catch-throw 10 mal in Josh's gist ist raise-rescue dauert eine lange Zeit, um backtrace Objekt zu erstellen.

Wenn Sie ohne Backtrace zu raise möchten, verwenden Sie Syntax:

raise <type>, <message>, <backtrace> 

Kasse my gist. raise without backtrace ist viel schneller als raise with backtrace.

April 2016 Update:

Ich habe my gist aktualisiert:

  • Fixed "brechen" test
  • Added Benchmark-Tests Ergebnisse für neuere Ruby-Version 2.1.8, 2.2.4, 2.3.0