Warum sollten wir vermeiden, Rettung in seiner Modifikatorform zu verwenden?

9

Ich werde Wert definieren. Aber dieser Wert kann im Wert des Schlüssels des Hashes sein. Ich verwende rescue für define Wert ist Null, wenn dieser Schlüssel nicht existiert. zum Beispiel

foo = bar[:a][:b][:c] rescue nil

Aber sag mir in der Praxis einen schlechten Stil, weil ich Rettung in seiner Modifikatorform benutze. Ich werde die Logik ändern, um die Check-Drei-Bedingung zu verwenden.

foo = bar[:a][:b][:c] if bar.key?(:a) && bar[:a].key?(:b) && bar[:a][:b].key?(:c)

Ich würde wirklich gerne wissen Warum sollten wir vermeiden, Rettung in seiner Modifikationsform in Schienen zu verwenden?

    
Edin Dzejo' 07.01.2017, 21:00
quelle

4 Antworten

14
  

Warum sollten wir vermeiden, Rettung in seiner Modifikationsform in Schienen zu verwenden?

Erstens, weil es alle Fehler verbirgt, einschließlich der erwarteten und der, die Sie nicht haben, und eine Decke rescue macht es zukünftigen Lesern Ihres Codes nicht klar < em> welche Fehler wurden erwartet oder unerwartet. Dies ist vielleicht kein Problem now , mit einem einfachen foo[:a][:b][:c] , aber zu irgendeinem Zeitpunkt könnte jemand diese Anweisung ändern, um foo[:a][:b][some_method] zu lesen und plötzlich alle Fehler, die sollten bubble aus some_method werden ebenfalls verschluckt.

Zweitens gibt es normalerweise eine bessere, weniger allumfassende Lösung, die expliziter entworfen wurde, um nur den Fehler zu behandeln, den Sie ignorieren wollen: Ein fehlender Index oder ein nil Rückgabewert.

In Ihrem Fall ist die Alternative nicht die massive if && && && , die Sie vorschlagen. Für einen Hash können Sie entweder dig verwenden alle Vorteile von rescue , ohne jede Art von Ausnahme zu verschlingen, die ausgelöst werden könnte:

%Vor%

Ebenso können Sie für verkettete Methodenaufrufe try (in Rails) oder den sicheren Navigationsoperator (in Ruby 2.3) verwenden:

%Vor%     
meagar 07.01.2017, 21:03
quelle
3

Die längere Form ist sicherer, ich würde die Kurzversion in der Produktion nicht verwenden, außer es gibt keinen anderen Weg. Ob Sie Prüfungen oder Ausnahmen verwenden, um Fehler zu vermeiden oder zu erfassen, hängt von der Situation ab. Ausnahmen sind teuer in der Prozessorzeit, so sind Ihre Benchmarks für zeitaufwendige Methoden, auf der anderen Seite eine Menge Prüfungen und noch nicht sicher ist, ist vielleicht noch schlimmer. Wenn die Lesbarkeit meines Codes durch eine Menge von Prüfungen verloren gehen würde und die Geschwindigkeit kein Faktor ist, benutze ich begin .. rescue oder def .. rettung, aber in diesem Fall ist es besser, eine bekannte Ausnahme wie diese zu retten.

> %Vor%

Was gibt

%Vor%

Fange immer die Art der Ausnahme und setze oder besser logge sie, ich benutze sie auch, um eine Variable @errors zu erzeugen, die für alle meine Skripte protokolliert und von einem separaten Tool überwacht wird.

    
peter 07.01.2017 22:57
quelle
1

Vermeiden

%Vor%

aus dem gleichen Grund wie

%Vor%

Weder gibt eine Ausnahmeklasse an und überspringt somit stillschweigend ALLE Fehler und nicht nur die erwartete. Sie sollten immer so genau wie möglich sein, wenn Sie Fehler beheben.

Außerdem entstehen beim Erstellen einer Ausnahme große Kosten.

Wenn Sie eine Exception auslösen, ist das Backtrace ausgefüllt, und in Rails bedeutet das Erstellen von 500 bis 1000 Strings mit Dateinamen und Zeilennummern, da Rails tendenziell einen tiefen Callstack hat. Wenn Sie also Ihre rescue nil in eine Schleife einfügen, kann es leicht passieren, dass Sie Tausende von String-Objekten erstellen, die niemals verwendet werden, und mit Rubys abgründiger Speicherbereinigung wirkt sich dies auf Ihre Leistung aus.

Versuchen Sie daher nach Möglichkeit, Alternativen zu verwenden, die keine Ausnahme auslösen

%Vor%     
akuhn 07.01.2017 22:29
quelle
0

Ein typisches Beispiel, warum es eine schlechte Idee ist:

%Vor%

Sie könnten viel Zeit verlieren, indem Sie überprüfen, dass bar wirklich {a: {b: {c: :something}}} hat und sich fragt, warum foo ist nil : Es gibt einen Tippfehler und rescue nil verbirgt es.

Alternativen finden Sie in @ meagars guter Antwort.

    
Eric Duminil 07.01.2017 21:20
quelle

Tags und Links