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:
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%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.
Wenn der erste Operand falsch ist ( nil
oder false
), dann wird der zweite Operand von &&
nicht ausgewertet, da falsy && whatever
immer falsy
Sie listen zwei verwandte Probleme auf:
nil
anstelle von false
zurückgibt. nil
, false
oder ein anderes Objekt auswertet, das nicht auf die nächste Methode in der Kette reagiert. 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:
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.
Wenn Sie nil && false
auswerten, bewerten Sie zwei separate Ausdrücke:
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.
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.
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.
&
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:
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.
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:
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:
Und !
"nistet" den Wert zweimal, was wir verwenden, um schnell etwas von einem Nicht-Wahr / Falsch-Wert in ein Wahr / Falsch zu konvertieren:
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:
Mit true
("and") müssen beide Seiten &&
sein, um ein true
result zu erhalten:
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.
Tags und Links ruby ruby-on-rails