Best Practice: Versuchen Sie es mit Rescue

73

Was ist eine bewährte Methode? Zu verwenden tryoder zu verwenden rescue?

user.try(:email)

VS

user.email rescue nil

post.try(:comments).try(:first).try(:author)

VS

post.comments.first.author rescue nil

Gibt es einen Unterschied bei der Verwendung dieser?

LuisVM
quelle

Antworten:

113

Versuch und Rettung dienen verschiedenen Zwecken. Der Zweck von tryist es, Sie davor zu bewahren, Folgendes tun zu müssen:

if user && user.email

Oder jede Situation, in der das übergeordnete Objekt möglicherweise Null sein kann, was einen NoMethodError in NilClass verursachen würde. Der Zweck von rescuebesteht darin, Ausnahmen zu behandeln, die durch Ihren Methodenaufruf ausgelöst werden. Wenn Sie erwarten, dass eine Ausnahme aufgerufen wird user.email, können Sie dies rescue niltun, um zu verhindern, dass die Ausnahme in die Luft sprudelt.

Im Allgemeinen würde ich sagen, vermeiden Sie die Verwendung, es rescue nilsei denn, Sie wissen explizit, welche Ausnahmen Sie retten, weil Sie möglicherweise eine andere Ausnahme retten, und Sie würden es nie erfahren, weil Sie es nicht sehen könnten rescue nil. Zumindest könnten Sie es vielleicht protokollieren:

begin
  ...some code...
rescue => ex
  logger.error ex.message
end
Jack Chu
quelle
Ich wünschte, dies hätte einen Link zur Testquelle.
New Alexandria
4
Hier ist das Dokument und die Quelle zu ActiveSuppot#try.
Jack Chu
7

Beide scheinen faul zu sein und können andere Käfer maskieren. Bist du sicher, dass du wirklich nichts erreichen willst? Vielleicht ist es besser, zuerst zu überprüfen, ob es Kommentare gibt, und den leeren Fall explizit abzudecken?

Adam Byrtek
quelle
4

Nichts ist etwas ist ein ausgezeichneter Vortrag von Sandi Metz, der hilft zu verstehen, warum @AdamByrtek genau richtig ist und warum wir alle die fehlgeschlagenen Fälle intelligenter und objektorientierter markieren solltenx ? y : nil

Jonathan_W
quelle
2
Tolles Gespräch, danke fürs Teilen, aber dies sollte ein Kommentar sein.
Stefan
Guter Punkt, danke. Werde das nächste Mal tun. Es ist meine erste Antwort, also ein bisschen aufgeregt :)
Jonathan_W