2013-03-09 8 views
9

David A. Schwarz in seinem Buch:Warum können wir `||` und `&&` nicht überschreiben?

[D] ie bedingte Zuweisungsoperator ||= sowie seine selten Cousin getupft & & =, welche beide die gleiche Art von Verknüpfung bieten als Die Pseudooperator-Methoden basieren jedoch auf Operatoren, nämlich || und &&, die Sie nicht überschreiben können.

Warum hat er speziell erwähnt, dass wir || und && nicht überschreiben können?

+10

Weil sie ein Teil der Sprache sind, keine Methoden. –

Antwort

11

Im Gegensatz zu einigen anderen Operatoren für Objekte, deren Verhalten logisch von der Klasse abhängen kann, sind die booleschen Operatoren Teil der Sprache. Wenn Sie einen Operator wie zB == haben, ist es logisch zu sagen, dass das Verhalten dieses Operators vom Objekttyp abhängt. Eine Zeichenfolge sollte Zeichen für Zeichen, ein Hash-Schlüssel-Wert-Tupel durch Schlüssel-Wert-Tupel usw. überprüfen. Das Verhalten von && und || basiert jedoch auf der -Definition der Definition von True und False, nicht irgendetwas Objektspezifisches. Wenn die Sprache es erlaubt, diese Operatoren zu überschreiben, könnte es kein konsistentes boolesches Modell geben, und diese Operatoren würden völlig nutzlos werden.

Zusätzlich gibt es auch eine Leistungsüberlegung. Weil && und || sind Kurzzirkeloperatoren, was bedeutet, dass, wenn das erste Argument zu, sagen wir, &&, wird falsch ausgewertet, der zweite wird nie einmal ausgewertet. Mit ||, wenn der erste Wert wahr ist, wird der zweite Wert nie ausgewertet. Dieses Verhalten wäre nicht möglich, wenn Sie diese Operatoren überschreiben könnten, da Ruby-Operatoren als Methoden überladen sind. Und alle Parameter müssen definitionsgemäß vor dem Aufruf der Methode ausgewertet werden. Somit geht die Leistungssteigerung und die Programmierfreundlichkeit eines Kurzschlussoperators verloren.

+2

Es ist durchaus möglich, faule Auswertungen in Ruby zu implementieren (oder in einer anderen Sprache mit erstklassigen Prozeduren): Umbrechen Sie einfach den Ausdruck, der in einem Lambda lazy ausgewertet werden soll. Ruby * hat * lambdas, noch besser, es hat * blocks *. Es wäre sicherlich möglich, bedingte Operatoren als Nachrichten in Ruby zu implementieren. Ich habe das nur zum Spaß gemacht. –

+0

@ JörgWMittag: Ture, daran habe ich nie gedacht. Obwohl ich sicher bin, dass das Kurzschließen auf Sprachniveau noch effizienter ist. – Linuxios

+0

@ JörgWMittag Wenn Sie in diesem Zusammenhang etwas teilen möchten, können Sie hier auch als Antwort angeben. Ich bin gespannt auf Ihre Erklärung in meinem Beitrag, was Sie gerade gesagt haben, linuxios. –

Verwandte Themen