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.newkautta 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