Nil und boolean in Ruby

8

Kann jemand die Gründe dafür erklären? Habe gerade 30 Minuten damit verbracht, herauszufinden, warum meine boolesche Methode nil zurückgegeben hat und habe herausgefunden, dass in Ruby:

%Vor%

Da nil ein falscher Wert ist, hätte ich erwartet, dass die Ausgabe von nil && true falsch ist. Es scheint auch gegen die Idee zu gehen, dass bedingte Operatoren einen booleschen Wert zurückgeben sollten.

Was ist der Grund dafür?

Aktualisieren

Es macht also Sinn, dass der boolesche Operator nicht kommutativ ist: d. h.

%Vor%

Für andere, die das sahen, war mein Problem, dass ich in Schienen eine Aussage hatte wie:

%Vor%

Aber wenn object.attr null ist, ist die Funktion null. Was in den meisten Fällen in Ordnung ist, aber wenn man boolesche Methoden aneinander kettet, nicht so sehr. Ich habe es stattdessen geändert:

%Vor%

Sie können das gleiche in Vanille Ruby mit tun:

%Vor%     
onetwopunch 29.01.2016, 18:04
quelle

4 Antworten

8

Die Anweisung durchläuft die Bedingungen in der Reihenfolge, stoppt, wenn ein falsches Ergebnis erhalten wird und gibt den Wert der letzten durchgeführten Auswertung zurück.

Im Gegensatz zu && , das bei einem falschen Wert endet, wird || stattdessen bei einem truthigen Wert stehen bleiben.

    
Edward 29.01.2016, 18:14
quelle
4

Wenn der erste Operand falsch ist ( nil oder false ), dann wird der zweite Operand von && nicht ausgewertet, da falsy && whatever immer falsy

ist     
Wand Maker 29.01.2016 18:07
quelle
1

Problem

Sie listen zwei verwandte Probleme auf:

  1. Sie sind verwirrt durch einen booleschen Ausdruck, der nil anstelle von false zurückgibt.
  2. Sie haben ein überraschendes Verhalten beim Verketten von Methoden, wenn eine der Methoden möglicherweise nil , false oder ein anderes Objekt auswertet, das nicht auf die nächste Methode in der Kette reagiert.

Null und falsch

In Ihren Beispielen verketten Sie Methoden, die manchmal in nil aufgerufen werden können. In Ruby ist Null ein falscher Wert (z. B. ist es nicht "wahr"), aber es ist auch nicht nicht . Überlegen Sie:

%Vor%

Sie stammen nicht einmal von derselben Klasse ab.

%Vor%

Es ist oft am besten, an nil als einen speziellen Wert zu denken, der "undefined" oder "nicht anwendbar" bedeutet. Es kann auch nützlich sein, sich keine Ähnlichkeit mit dem speziellen Datenbankwert von null vorzustellen. Nil (wie null) ist nicht wahr, falsch oder leer. Wenn Sie dies verstehen, können Sie viele verwirrende Ausnahmen vermeiden.

Kurzschlussauswertung

Wenn Sie nil && false auswerten, bewerten Sie zwei separate Ausdrücke:

%Vor%

Der Ausdruck nil ist nicht wahr und daher kurzgeschlossen und wertet den Ausdruck false niemals aus. Daher gibt der Ausdruck nil && false korrekt den Wert nil statt false zurück. Dies ist eine Quelle der Überraschung für einige Leute, aber erwartetes Verhalten für erfahrene Rubyists.

Lösungen

Zusätzlich zu Kurzschlussausdrücken oder Postausdruck-Bedingungen wie:

%Vor%

sollten Sie die Methode Rails Object # try oder den sicheren Navigationsoperator Ruby 2.3.0 in Betracht ziehen.

Verwenden Sie Object # try oder Safe Navigation Operator

Objekt # try

Wenn Sie Rails verwenden, ist die Methode Objekt # try häufig Möglichkeit, das Aufrufen von Methoden für nil oder andere Objekte zu vermeiden, die #respond_to? die verkettete Methode. Zum Beispiel:

%Vor%

Dies ist ähnlich, aber nicht genau äquivalent zu:

%Vor%

Ruby 2.3.0 führt die sichere Navigation ein Operator ( & ), der ähnliche Funktionen wie Rubys Kern bietet.

Der & sichere Navigationsoperator

Ruby 2.3.0 hat einen neuen Safe eingeführt Navigationsoperator . Dies scheint ein tatsächlicher Operator zu sein, keine Methode. Mit diesem Operator können Sie Methoden verketten, solange der Ausdruck auf der linken Seite truthy ist. Zum Beispiel:

%Vor%

Da es Methoden kettet und Vergleichsoperatoren wie > eher Methoden als Parser-Token sind, können Sie jetzt Dinge wie:

tun %Vor%

Ob Sie object.attr&. > something eleganter, lesbarer oder nützlicher als andere Konstrukte finden, ist eine Frage der Meinung, aber es ist in vielen Fällen sicherlich eine Option. YMMV.

    
Todd A. Jacobs 29.01.2016 22:05
quelle
0

Es ist gut, Variablen / Werte "Wahrhaftigkeit" zu verstehen:

Zuerst schauen wir uns Rubys Idee von wahr und falsch an:

%Vor%

Eine kürzere Form dieses if / else verwendet das Ternär:

%Vor%

Weiter damit:

%Vor%

Beachten Sie, dass nil bei Verwendung als Bedingung wie false wirkt, während 0 wahr ist. (Perl behandelt false und 0 als falsche Werte in Tests, was ein verwirrender Punkt beim Wechsel zu Ruby ist.)% Co_de% ist wahr, und im Grunde sind in% nur 1 und nil falsch und alles sonst ist wahr.

false führt ein "nicht" aus und kehrt die Wahrheit des Wertes um:

%Vor%

Und ! "nistet" den Wert zweimal, was wir verwenden, um schnell etwas von einem Nicht-Wahr / Falsch-Wert in ein Wahr / Falsch zu konvertieren:

%Vor%

Wenn Sie wissen, wie diese in Ruby funktionieren, ist es einfacher, den Code anderer Leute zu verstehen, da Sie oft !! und ! sehen.

All das führt zurück zur Verwendung von !! und && . Mit || ("oder") muss nur eine Seite || sein, um ein true result zurückzugeben:

%Vor%

Mit true ("and") müssen beide Seiten && sein, um ein true result zu erhalten:

%Vor%

Verwechsle nicht true und || und or und && . Sowohl and als auch !! machen ähnliche Dinge, und or und && , jedoch werden ihre Tests zu unterschiedlichen Zeiten in einem Ausdruck stattfinden. Das ist eine Rangfolge und es ist sehr wichtig zu wissen, aber das ist eine andere Frage. Sie können viele Informationen dazu mit einfachen Suchen finden.

    
the Tin Man 29.01.2016 19:10
quelle

Tags und Links