Ruby Operators: Double Pipe Equals
”Hey, what does that ||=
mean in your ruby code?”
ensimmäisessä blogikirjoituksessani ohjelmoijana ajattelin, että olisi sopivaa selittää yksi kysymyksistä, joita minulta kysyttiin ensimmäisen päiväni aikana Flatironin koulussa. Tämä on kysymys, jonka olin keksinyt noin kuukausi sitten ja joka johti minut alas kaninkoloon ruby-foorumeilla ja reddit-viesteissä (säästän sinut vaivalta ja linkitän muutamia parempia lähteitä tämän viestin alareunassa).
kiista ”double-pipe equals”: n takana keskittyy siihen, miten operaattori pitäisi kääntää, mutta haluaisin keskittyä tähän viestiin niihin sovelluksiin, joita olen sille löytänyt. Mitä siis ||=
tekee? Oma määritelmäni on, että” double-pipe equals”on operaattori, joka antaa arvon, aivan kuten =
tai klassinen tehtäväoperaattorimme, mutta suorittaa tehtävän vain, jos operaatiomme vasen puoli palaa false
tai nil
.
anna minun osoittaa.
a = nil
b = 4
a = b #=> 4
a #=> 4
kun a
asetetaan nil
, on helppo nähdä, että asettamalla ”yhtä suuri” b
käyttämällä klassista tehtäväoperaattoria palauttaisi A: n arvon 4
. Mutta mitä jos käyttäisimme ”double-pipe equals” sen sijaan?
a = nil
b = 4
a ||= b #=> 4
a #=> 4
tässä tapauksessa saadaan sama tulos. Kun a
on asetettu nil
(tai mikä tahansa, joka arvioi false
||=
operaattori toimii samalla tavalla kuin =
olisi. Katsotaanpa esimerkkiä, jossa a
annetaan” totuudellinen ” arvo.
a = 2
b = 4
a ||= b #=> 2
a #=> 2
yllä olevassa esimerkissä a säilyttää alkuperäisen arvonsa, vaikka sitä on operoitu meidän ”kaksoisputkemme yhtäsuuruuden”kautta. Näin tapahtuu, koska ||
toimii tässä menetelmässä ”piirinä”. Kuten Peter Cooper selittää,
Jos vertailun vasen puoli on totta, ei oikeaa puolta tarvitse tarkistaa.
kun ruby näki, että a
oli jo annettu 2
, se lakkasi suorittamasta koodiamme.
Jos olen havainnut tällaisen ehdollisen tehtävän hyödyllisimmäksi, se on iteraatiossa. Iteroidaan joukko suosittuja hedelmiä käyttäen ||=
– menetelmää, jolla jokainen merkkijonoista annetaan a
.
a = nil
array =
array.each do |fruit|
a ||= fruit
end #=> a #=> "apple"
voimme nähdä, että iterointimme jälkeen a
on annettu ryhmämme ensimmäiselle merkkijonolle, "apple”
. Kun a
tulee "apple”
, meidän ”kaksoisputkemme yhtäsuuruus” ei anna minkään sen oikealla puolella olevan muuttaa muuttujaamme.
vaikka Rubylla on menetelmiä, joilla voidaan palauttaa joukon ensimmäinen alkio ilman iterointia, voi joskus olla hyödyllistä valvoa, onko muuttuja annettu ”totuudellisella” arvolla. Alla on koodinpätkä eräästä viimeaikaisesta laboratoriostani, jossa löysin ||=
erityisen hyödylliseksi.
class School attr_reader :roster def initialize(name)
@name = name
@roster = {}
end def add_student(name, grade)
@roster ||=
@roster << name
endend
Tässä olen määritellyt luokan, School
, sekä pari menetelmää. Tärkeintä on ymmärtää, että soittamalla roster
jostakin minun School
Luokka, Aion palauttaa listani oppilaista arvosanojen hajautuksena osoittaen kuhunkin luokkaan liittyviä oppilaita.
Lets instantiate a example school and populate some students.
metro = School.new("Metro High")
metro.add_student("Jared", 9)
metro.roster #=> {9=>}metro.add_student("Graham", 9)
metro.roster #=> {9=>}
lisätäkseni oppilaan roster
minun School
instanssin, minun on läpäistävä add_student
method a name
ja grade
. Kuitenkin voimme nähdä, että kun lisäsin "Graham”
ja hänen vastaavan arvosanansa, 9
, hänen nimensä lisättiin olemassa olevaan joukkoon, joka syntyi, kun lisäsin "Jared”
. Tämä on ||=
. Tällöin ”kaksoisputki on yhtä kuin”-operaattori tunnusti, että arvosanaavain on jo lisätty ja
Jos minun add_student
menetelmää olisi käytetty =
sijasta ||=
, olisin korvannut ylioppilaskirjoitukseni "Jared”
kun lisäsin toisen luokan oppilaan 9
.