Articles

Ruby-Operatoren: Double Pipe Equals

„Hey, was bedeutet das ||= in Ihrem Ruby-Code?“

In meinem ersten Blogbeitrag als Programmierer dachte ich, es wäre angebracht, eine der Fragen zu erklären, die mir an meinem ersten Tag an der Flatiron School gestellt wurden. Dies ist eine Frage, die ich vor ungefähr einem Monat gestellt hatte und die mich in ein Kaninchenloch von Ruby-Foren und Reddit-Posts geführt hat (ich erspare Ihnen die Mühe und verlinke einige der besseren Quellen am Ende dieses Beitrags).

Die Kontroverse hinter „Double-Pipe equals“ dreht sich darum, wie der Operator übersetzt werden soll, aber ich möchte diesen Beitrag auf die Anwendungen konzentrieren, die ich dafür gefunden habe. Also, was genau macht ||= ? Meine eigene Definition ist, dass „double-pipe equals“ ein Operator ist, der einen Wert zuweist, ähnlich wie = oder unser klassischer Zuweisungsoperator, aber die Zuweisung nur vervollständigt, wenn die linke Seite unserer Operation false oder nil .

Lassen Sie mich demonstrieren.

a = nil
b = 4
a = b #=> 4
a #=> 4

Wenn a auf nil , ist es leicht zu erkennen, dass das Setzen von a „equal“ auf b mit dem klassischen Zuweisungsoperator a mit dem Wert 4. Aber was wäre, wenn wir stattdessen „Double-Pipe equals“ verwenden würden?

a = nil
b = 4
a ||= b #=> 4
a #=> 4

In diesem Fall erhalten wir das gleiche Ergebnis. Wenn a auf nil gesetzt ist (oder irgendetwas, das zu false ausgewertet wird), funktioniert der Operator ||= genauso wie = . Schauen wir uns ein Beispiel an, in dem a einen „truthy“ -Wert erhält.

a = 2
b = 4
a ||= b #=> 2
a #=> 2

Im obigen Beispiel behält a seinen ursprünglichen Wert bei, obwohl es über unsere „Double-Pipe equals“ bearbeitet wurde. Dies geschieht, weil die || bei dieser Methode als „Schaltung“ fungiert. Wie Peter Cooper erklärt,

Wenn die linke Seite des Vergleichs wahr ist, muss die rechte Seite nicht überprüft werden.

Als Ruby sah, dass a bereits dem Wert von 2 zugewiesen war, hörte es auf, unseren Code auszuführen.

Wo ich diese Art der bedingten Zuweisung am nützlichsten gefunden habe, ist in der Iteration. Lassen Sie uns mit unserer ||= -Methode ein Array beliebter Früchte durchlaufen, um jede der Zeichenfolgen a zuzuweisen.

a = nil
array =
array.each do |fruit|
a ||= fruit
end #=> a #=> "apple"

Wir können sehen, dass nach unserer Iteration a der ersten Zeichenfolge in unserem Array zugewiesen wird, "apple” . Nachdem a zu "apple” wird, lässt unsere „Double-Pipe equals“ nichts rechts davon unsere Variable neu zuweisen.Während Ruby Methoden hat, die das erste Element eines Arrays ohne Iteration zurückgeben können, kann es manchmal nützlich sein zu kontrollieren, ob einer Variablen ein „truthy“ -Wert zugewiesen wurde oder nicht. Unten ist ein Codeausschnitt aus einem meiner letzten Labors, in dem ich ||= besonders nützlich fand.

class School attr_reader :roster def initialize(name) 
@name = name
@roster = {}
end def add_student(name, grade)
@roster ||=
@roster << name
endend

Hier habe ich eine Klasse definiert, School , zusammen mit ein paar Methoden. Das Wichtigste zu verstehen ist, dass ich durch Aufrufen von roster in einer Instanz meiner School Klasse meine Schülerliste zurückgeben möchte als Hash von Noten, die auf ein Array von Schülern verweisen, die jeder Klasse zugeordnet sind.

Lässt eine Beispielschule instanziieren und einige Schüler auffüllen.

metro = School.new("Metro High")
metro.add_student("Jared", 9)
metro.roster #=> {9=>}metro.add_student("Graham", 9)
metro.roster #=> {9=>}

Um einen Schüler zur roster meiner School Instanz hinzuzufügen, muss ich die add_student Methode a name und ein grade. Wir können jedoch sehen, dass, als ich "Graham” und seine entsprechende Note 9 hinzufügte, sein Name dem vorhandenen Array hinzugefügt wurde, das erstellt wurde, als ich "Jared” hinzufügte. Dies ist die Magie von ||= . In diesem Fall erkannte der Operator „Double-pipe equals“, dass bereits ein Notenschlüssel hinzugefügt wurde, und

Hätte meine add_student -Methode verwendet = anstelle von ||=, Ich hätte meinen Schülereintrag überschrieben "Jared” als ich einen anderen schüler in der Klasse 9 .