Ruby Operators: dubbelrör är lika med
” Hej, vad betyder det ||=
I din ruby-kod?”
i mitt första blogginlägg som programmerare tyckte jag att det skulle vara lämpligt att förklara en av de frågor som jag ställdes under min första dag på Flatiron School. Det här är en fråga som jag hade kommit upp för ungefär en månad sedan och en som ledde mig ner i ett kaninhål av ruby-forum och reddit-inlägg (jag sparar dig besväret och länkar några av de bättre källorna längst ner i det här inlägget).
kontroversen bakom ”double-pipe equals” är centrerad kring hur operatören ska översättas men jag skulle vilja fokusera det här inlägget på de applikationer som jag har hittat för det. Så, vad exakt gör ||=
? Min egen definition är att ”double-pipe equals”är en operatör som tilldelar ett värde, ungefär som =
eller vår klassiska uppdragsoperatör, men kommer bara att slutföra uppdraget om vänster sida av vår operation returnerar false
eller nil
.
Låt mig visa.
a = nil
b = 4
a = b #=> 4
a #=> 4
med a
inställd på nil
är det lätt att se att Inställning av ”lika” till b
med den klassiska tilldelningsoperatören skulle returnera a med värdet 4
. Men vad händer om vi använde ”dubbelrör lika” istället?
a = nil
b = 4
a ||= b #=> 4
a #=> 4
i det här fallet får vi samma resultat. När a
är inställd på nil
(eller något som utvärderar till false
), fungerar ||=
operatorn på samma sätt som =
skulle. Låt oss titta på ett exempel där a
ges ett ”truthy” värde.
a = 2
b = 4
a ||= b #=> 2
a #=> 2
i exemplet ovan behåller a sitt ursprungliga värde även om det har drivits genom vårt”dubbelrör lika”. Detta händer eftersom ||
fungerar som en ”krets” i denna metod. Som Peter Cooper förklarar,
om den vänstra sidan av jämförelsen är sant, finns det ingen anledning att kontrollera den högra sidan.
När ruby såg att a
redan tilldelades värdet av 2
, slutade det att köra vår kod.
Där jag har hittat den här typen av villkorlig uppgift mest användbar är i iteration. Låt oss iterera genom en rad populära frukter, med hjälp av vår||=
metod för att tilldela var och en av strängarna tilla
.
a = nil
array =
array.each do |fruit|
a ||= fruit
end #=> a #=> "apple"
Vi kan se att, efter vår iteration, a
tilldelas den första strängen i vår array, "apple”
. Efter a
blir "apple”
, kommer vårt” dubbelrör lika ” inte att låta något till höger om det tilldela vår variabel.
medan ruby har metoder som kan returnera det första elementet i en array utan iteration, kan det ibland vara användbart att kontrollera om en variabel har tilldelats ett ”truthy” – värde eller inte. Nedan finns ett kodavsnitt från ett av mina senaste laboratorier där jag hittade ||=
särskilt användbart.
class School attr_reader :roster def initialize(name)
@name = name
@roster = {}
end def add_student(name, grade)
@roster ||=
@roster << name
endend
Här har jag definierat en klass, School
, tillsammans med ett par metoder. Det viktigaste att förstå är att genom att ringa roster
på en instans av min School
klass, ser jag tillbaka min lista över studenter som en hash av betyg som pekar på en rad elever som är associerade med varje betyg.
låter instansiera ett exempel skola och fylla vissa elever.
metro = School.new("Metro High")
metro.add_student("Jared", 9)
metro.roster #=> {9=>}metro.add_student("Graham", 9)
metro.roster #=> {9=>}
för att lägga till en student till roster
I min School
instans måste jag skicka add_student
metod a name
och en grade
. Vi kan dock se att när jag lade till "Graham”
och hans motsvarande betyg, 9
, lades hans namn till den befintliga arrayen som skapades när jag lade till "Jared”
. Detta är magin med ||=
. I det här fallet erkände operatören ”double-pipe equals” att en betygsnyckel redan har lagts till och
hade min add_student
metod som används =
istället för ||=
, skulle jag ha skrivit över min studentpost "Jared”
när jag lade till en annan elev i betyg 9
.