operatorii Ruby: țeavă dublă este egal
„Hei, ce înseamnă că||=
înseamnă în codul ruby?”
în prima mea postare pe blog ca programator, m-am gândit că ar fi potrivit să explic una dintre întrebările care mi s-au pus în prima mea zi la școala Flatiron. Aceasta este o întrebare pe care am venit în urmă cu aproximativ o lună și una care m-a condus într-o gaură de iepure de forumuri ruby și postări reddit (vă voi salva problemele și voi lega câteva dintre sursele mai bune din partea de jos a acestui post).
controversa din spatele „Double-pipe equals” este centrat în jurul valorii de modul în care operatorul ar trebui să fie tradus, dar aș dori să se concentreze acest post pe aplicațiile pe care le-am găsit pentru ea. Deci, ce anume face ||=
? Definiția mea este că” Double-pipe equals”este un operator care atribuie o valoare, la fel ca =
sau operatorul nostru clasic de atribuire, dar va finaliza atribuirea numai dacă partea stângă a operației noastre returnează false
sau nil
.
permiteți-mi să vă demonstrez.
a = nil
b = 4
a = b #=> 4
a #=> 4
cu a
setat la nil
, este ușor de văzut că setarea unui „egal” cu b
folosind operatorul de atribuire clasic ar returna a cu valoarea . Dar dacă am folosi în schimb” dublu-pipe equals”?
a = nil
b = 4
a ||= b #=> 4
a #=> 4
în acest caz, obținem același rezultat. Când a
este setat la nil
(sau orice se evaluează la false
), operatorul ||=
funcționează la fel ca =
div > ar fi. Să ne uităm la un exemplu în care a
i se dă o valoare „adevărată”.
a = 2
b = 4
a ||= b #=> 2
a #=> 2
în exemplul de mai sus, a își păstrează valoarea inițială chiar dacă a fost operată prin „dublu-pipe equals”. Acest lucru se întâmplă deoarece ||
acționează ca un „circuit” în această metodă. După cum explică Peter Cooper,
dacă partea stângă a comparației este adevărată, nu este nevoie să verificați partea dreaptă.
când ruby a văzut căa
a fost deja atribuit valorii2
, a încetat să mai execute codul nostru.
unde am găsit acest tip de atribuire condiționată cel mai util este în iterație. Să iterăm printr-o serie de fructe populare, folosind metoda noastră ||=
pentru a atribui fiecare șir la a
.
a = nil
array =
array.each do |fruit|
a ||= fruit
end #=> a #=> "apple"
putem vedea că, după iterația noastră,a
este atribuit primului șir din matricea noastră,"apple”
. După cea
devine"apple”
, „dublu-pipe este egal” nu va lăsa nimic din dreapta să reatribuie variabila noastră.în timp ce ruby are metode care pot returna primul element al unei matrice fără iterație, uneori poate fi util să se controleze dacă o variabilă a fost sau nu atribuită cu o valoare „adevărată”. Mai jos este un fragment de cod dintr-unul din laboratoarele mele recente unde am găsit ||=
deosebit de util.
class School attr_reader :roster def initialize(name)
@name = name
@roster = {}
end def add_student(name, grade)
@roster ||=
@roster << name
endend
aici, am definit o clasă,School
, împreună cu câteva metode. Lucrul cheie de înțeles este că apelând roster
pe o instanță a clasei mele School
, caut să returnez lista mea de studenți ca un hash de note care indică o serie de studenți asociați cu fiecare clasă.
permite instanțierea unui exemplu de școală și popularea unor elevi.
metro = School.new("Metro High")
metro.add_student("Jared", 9)
metro.roster #=> {9=>}metro.add_student("Graham", 9)
metro.roster #=> {9=>}
pentru a adăuga un student la roster
din School
instanță, trebuie să treacă add_student
metoda a name
și un grade
. Cu toate acestea, putem vedea că atunci când am adăugat "Graham”
și nota sa corespunzătoare, 9
, numele său a fost adăugat la matricea existentă care a fost creată atunci când am adăugat "Jared”
. Aceasta este magia ||=
. În acest caz, operatorul „Double-pipe equals” a recunoscut că o cheie de grad a fost deja adăugată și
a avut add_student
metoda utilizată =
în loc de ||=
, aș fi suprascris intrarea mea de student "Jared”
când am adăugat un alt elev în clasa 9
.