Self wewnątrz definicji klasy

Czy jakiś guru może mi wytłumaczyć dlaczego tak się dzieje w tym kodzie?

[code]class Klass
attr :x, true

def initialize
@x=999
end

def test
p x, self.x, x==self.x, x===self.x, @x==x, @x===x, @x==self.x, @x===self.x
p ‘----------- x = self.x’
self.x= 1
x= 2
p x, self.x, x==self.x, x===self.x, @x==x, @x===x, @x==self.x, @x===self.x
p ‘----------- x != self.x’
end
end

c = Klass.new
c.test
p c.x[/code]
Pierszy wniosek “x=” tworzy nową zmienną lokalną, nie jest szukana metoda “x=”. A potem już zmienna lokalna x jest przed metodą x.
Drugi wniosek: opuszczanie self w definicji metody może być przyczyną wielu groźnych błedów (a tyle jest przykładów bez self, nawet w tym forum) !!!

A poniżej kod gdzie raz self jest konieczny a drugi raz nie (???). Bez self się nawet nie wykona.

[code]class Klass
attr :x, true

def initialize
@x=0
end

def licz
self.x = x + 1
end
end

c = Klass.new
p c.licz
p c.licz
p c.licz[/code]

Pisałem o tym jakiś czas temu: http://blog.drogomir.com/articles/2008/11/15/to-self-or-not-to-self :slight_smile:

EDIT:

Właściwie to jak teraz przeczytałem tego posta, to słabo tam to opisałem.

Ogólnie chodzi o to, że w momencie odczytywania interpreter najpierw sprawdza czy nie ma takiej zmiennej, a później metody. Więc jeżeli masz zmienną x i metodę instancji x, to zostanie wykorzystana zmienna x. Jeżeli nie ma zmiennej to interpreter wykonuje metodę x.

Przy zapisywaniu nie interpreter nie może przewidzieć, czy chcesz stworzyć nową zmienną czy wywołać metodę x=, więc jeżeli nie doda się self na początku, to stworzy się nowa zmienna.

EDIT2:

A co do wielu groźnych błędów :wink:

Wszystko jest dla ludzi. Ja też często opuszczam self. Trzeba tylko pamiętać o konsekwencjach użycia lub nie self przy zapisywaniu.

Za to bardzo nie lubię jak ktoś pisze czasami z self, a czasami bez w odwołaniu do tej samej metody (wizualnie wygląda to tak jak odwołanie do dwóch różnych metod i czasami trzeba przez chwilę pomyśleć zanim się zrozumie).