Vad är en privat metod i Ruby?
det är en typ av metod som du bara kan ringa inifrån klassen där den är definierad.
detta låter dig styra åtkomst till dina metoder.
en Rubinmetod kan vara:
- privat
- Offentlig (standard)
- skyddad
som standard är alla dina metoder public
.
vem som helst kan använda dem!
men du kan ändra detta genom att göra en metod private
eller protected
.
Varför är detta användbart?
eftersom du kan göra dessa metoder lättare att ändra.
Tänk dig att du skriver ett kodbibliotek som kommer att användas i några olika projekt på jobbet.
när dessa projekt implementerar ditt bibliotek kommer de att anropa metoder för de klasser du har skapat.
nu:
du släpper en ny version…
men du bestämde dig för att ändra namnet på en public
– metod.
det kommer att producera fel på varje projekt som använder den här metoden!
kom ihåg detta:
genom att ha mindre offentliga metoder ökar du förändringsfriheten i din klass.
Låt oss se några kodexempel!
förstå privata metoder i Ruby
har du någonsin sett felmeddelandet ”privat metod kallad”?
den här:
self.puts 123# NoMethodError: private method `puts' called
då har du försökt använda en private
– metod felaktigt.
du kan bara använda en privat metod i sig.
exempel:
puts 123
det är samma metod, men du måste kalla det så här.
privata metoder kallas alltid inom ramen för self
.
med andra ord …
du kan bara använda privata metoder med:
- andra metoder från samma klass
- metoder ärvda från den överordnade klassen
- metoder som ingår från en modul
det betyder att du inte kan ringa privata metoder utanför den klass som definierar dem.
eftersom det skulle kräva en”explicit mottagare”.
om inte…
du använder en metod som send
för att kringgå denna regel.
send(:puts, "apple")
hur definierar du en private
metod?
def bacon "private bacon"endprivate :bacon
ordet private
i sig är inte ett nyckelord, det är en metod som definieras på modulen Kernel
.
var att sätta dina privata metoder
det är normalt att en klass har mer än en privat metod.
var placerar du dessa metoder?
gör detta:
class Food def public_method end private def bacon end def orange end def coconut endend
varje instansmetod efter private
blir en privat metod.
du kan använda
private_class_method :method_name
om du vill definiera en klassmetod som privat
det är ett vanligt mönster att definiera alla dina offentliga metoder först och sedan definiera dina private
metoder tillsammans i slutet av klassen.
offentliga metoder
Offentliga är standardmetodens synlighet i Ruby.
här är ett exempel:
def orange "Vitamin C"end
om du har ett objekt food
som definierar orange
kan du kalla det så här:
food.orange
om en metod har gjorts privat eller skyddad kan du göra den offentlig igen.
public :orange
Vad är en skyddad metod?
skyddade metoder är mindre vanliga.
de är som private
metoder, men du kan ringa dem på ett objekt & inte bara direkt.
om du försöker det här exemplet med privat får du ett felmeddelande:
class Food def initialize(name) @name = name end def ==(other) name == other.name end protected attr_reader :nameendfood = Food.new("chocolate")puts food == food
du får felet eftersom name
skulle vara privat så att du inte kan göra other.name
.
men med protected
fungerar den här koden!
privata vs skyddade metoder
det är skillnaden, det faktum att protected
håller metoden private
, men det låter dig också ringa den metoden på ett objekt.
med privat kan du bara göra name
, med skyddad kan du göra object.name
.
När ska du använda skyddad?
endast om du har ett mycket specifikt fall, som metoden equals (==
).
Ruby-dokumentationen rekommenderar att du använder private
istället för protected
när det är möjligt.
och det finns denna anteckning:
”en skyddad metod är långsam eftersom den inte kan använda inline cache.”
jag var nyfiken på detta så jag sprang några riktmärken:
public: 2813891.9 i/sprivate: 2699273.8 i/sprotected: 2572122.0 i/s
det är en skillnad på 8,5% i prestanda.
Video Tutorial
sammanfattning
du har lärt dig om Ruby metod synlighet, offentliga, privata & skyddade metoder. Dessa är inte Ruby nyckelord, de är metoder själva definierade på klassen Module
.