Understanding ’self’in Ruby
Today I’ d like to talk about self
. Jos olet ohjelmoinut Rubya jonkin aikaa, olet todennäköisesti sisäistänyt ajatuksen self
. Aina kun lukee tai kirjoittaa ohjelmaa, self
on siellä takaraivossa.
mutta vähemmän kokeneille Rubyisteille self
voi olla hämmentävää. Se muuttuu koko ajan, mutta sitä ei näy koodissa. Sinun vain odotetaan tietävän.
suuri osa aloittelijan kohtaamista ongelmista johtuu siitä, ettei ymmärrä self
. Jos olet joskus ”kadottanut” instanssimuuttujan tai ihmetellyt, mitä dataa Mixille näkyy, niin se johtuu siitä, ettet ymmärtänyt self
tässä yhteydessä.
tässä viestissä käydään läpi self
erilaisia arjen tilanteita.
mikä on itse?
olet ehkä kuullut ihmisten sanovan, että kaikki Rubyssa on objektia. Jos se on totta, se tarkoittaa, että jokainen kirjoittamasi koodi ”kuuluu” jollekin esineelle.
self
on erityinen muuttuja, joka osoittaa objektia, joka ”omistaa” parhaillaan suoritettavan koodin. Ruby uses self
everwhere:
- esimerkiksi muuttujat:
@myvar
- menetelmän ja jatkuvan haun osalta
- määriteltäessä menetelmiä, luokkia ja moduuleja.
teoriassa self
on melko ilmeinen. Käytännössä hankalia tilanteita tulee kuitenkin helposti. Siksi kirjoitin tämän postauksen.
Examples of self
käymme nyt läpi useita esimerkkejä. Jos ensimmäiset tuntuvat liian alkeellisilta, jatka lukemista. He edistyvät.
instanssimenetelmän sisällä
alla olevassa koodissa reflect
on instanssimenetelmä. Se kuuluu Ghost.new
kautta luotuun kohteeseen. self
viittaa siis kyseiseen kohteeseen.
class Ghost def reflect self endendg = Ghost.newg.reflect == g # => true
Luokkamenetelmän sisällä
tässä esimerkissä reflect
on luokkamenetelmä Ghost
. Luokkamenetelmillä Luokka itse ”omistaa” menetelmän. self
pistettä luokkaa.
class Ghost def self.reflect self endendGhost.reflect == Ghost # => true
se toimii samalla” Luokka ” menetelmiä sisällä moduulit. Esimerkiksi:
module Ghost def self.reflect self endend Ghost.reflect == Ghost # => true
muista, että luokat ja moduulit käsitellään Rubyssa objekteina. Joten tämä käyttäytyminen ei ole kovin erilainen kuin esimerkiksi metodi käyttäytyminen näimme ensimmäisessä esimerkissä.
luokan tai moduulin määritelmän sisällä
yksi Rubyn ominaisuus, joka tekee siitä niin hyvän sopivaksi Railsin kaltaisiin kehyksiin, on se, että voit suorittaa mielivaltaista koodia luokan ja moduulin määritysten sisällä. Kun laitat koodin luokan/moduulin määritelmän sisään, se toimii kuten mikä tahansa muu Ruby-koodi. Ainoa todellinen ero on arvo self
.
kuten alla näkyy, self
viittaa luokkaan tai moduuliin, jota ollaan määrittelemässä.
class Ghost self == Ghost # => trueend module Mummy self == Mummy # => trueend
Inside mixin-menetelmät
Sekamenetelmät käyttäytyvät aivan kuten” normaalit ” instanssi-tai luokkamenetelmät, kun kyseessä on self
. Tässä on järkeä. Muuten mixin ei pystyisi olemaan vuorovaikutuksessa sen kanssa, mihin luokkaan sekoitit sen.
Instanssimenetelmät
vaikka reflect
menetelmä määriteltiin moduulissa, sen self
on sen luokan instanssi, johon se sekoitettiin.
module Reflection def reflect self endend class Ghost include Reflectionendg = Ghost.newg.reflect == g # => true
Luokkamenetelmät
kun meillä extend
A luokka sekoittuu luokkamenetelmissä, self
käyttäytyy täsmälleen samalla tavalla kuin normaaleissa luokkamenetelmissä.
module Reflection def reflect self endend class Ghost extend ReflectionendGhost.reflect == Ghost # => true
sisällä metaclass
mahdollisuudet ovat olet nähnyt tämän suositun pikakuvakkeen määritellä paljon luokan menetelmiä kerralla.
class Ghost class << self def method1 end def method2 end endend
class << foo
syntaksi on oikeastaan aika mielenkiintoinen. Sen avulla voit käyttää objektin metaklassikko – jota kutsutaan myös ”singleton luokka” tai ”eigenclass.”Aion kattaa metaclasses syvällisemmin tulevassa postitse. Mutta nyt, sinun tarvitsee vain tietää, että metaclass on missä Ruby tallentaa menetelmiä, jotka ovat ainutlaatuisia tiettyyn kohteeseen.
jos pääsee self
class << foo
lohkon sisältä, saa metaklassikon.
class << "test" puts self.inspectend# => #<Class:#<String:0x007f8de283bd88>
minkä tahansa luokan ulkopuolella
jos käytät koodia minkä tahansa luokan ulkopuolella, Ruby antaa silti self
. Se viittaa ”main”, joka on esimerkkiObject
:
puts self.inspect # => main