2012-08-23 111 views
13

有人可以解釋初始化「自我」和定義類時有@variables之間的區別嗎?Ruby類:初始化自己與@variable

下面是一個例子

class Child < Parent 
    def initialize(self, stuff): 
    self.stuff = stuff 
    super() 
    end 
end 

因此,在這種情況下,我豈不是能夠與@stuff取代self.stuff?有什麼不同?另外,super()只是意味着什麼是在父初始化方法的孩子應該只是繼承它的權利?

+1

樓下,你會發現優秀的答案爲第一部分你的問題。當計算'super()'時,父類的初始化方法被調用時沒有任何參數。這是紅寶石中罕見的情況之一,您不能忽略簡單方法調用的括號。如果你這樣做,超類的初始化方法被稱爲**,並且你傳遞給'Child'類的初始化方法的參數**。 – rathrio

+2

看起來你在Ruby和Python之間感到困惑(你是否想同時學習兩者?)在Ruby中,你不會在方法參數列表後加':',並且'initialize'不會獲得對「自我」的引用。在Python中,'self'被顯式地傳遞給構造函數(或者在Python中調用的任何東西),並且'initialize'方法看起來與它在Python中的外觀非常相似。在Ruby中,您始終可以引用'self'而不必將其明確地傳遞給方法。 –

回答

37

一般來說,不,self.stuff = stuff@stuff = stuff是不同的。前者在對象上調用stuff=,而後者則直接設置實例變量。前者調用可能是公共的方法(除非在類中專門聲明爲私有方法),而後者總是設置私有實例變量。

通常,它們看起來是相同的,因爲通常在類上定義attr_accessor :stuffattr_accessor大致等於以下內容:

def stuff 
    @stuff 
end 

def stuff=(s) 
    @stuff = s 
end 

因此,在這種情況下,它們在功能上是相同的。但是,它可以定義的公共接口允許不同的結果和副作用,這將使這兩個「分配」明顯不同:

def stuff 
    @stuff_called += 1 # Keeps track of how often this is called, a side effect 
    return @stuff 
end 

def stuff=(s) 
    if s.nil?    # Validation, or other side effect. This is not triggered when setting the instance variable directly 
    raise "Argument should not be nil" 
    end 
    @stuff = s 
end 
5

實際上,您不能使用self.stuff=,除非您專門創建attr_writer來修改該值。

事實上,這是等價的:

class Child 
    attr_writer :stuff 
end 

class Child 
    def stuff=(val) 
    @stuff = val 
    end 
end 

更常見的是使用一個attr_writer如果這是你想要的功能,而不是明確的方法。但是如果您想執行額外的錯誤檢查或更改分配的工作方式,您通常會使用顯式方法。

要你的時候使用@stuff =以及何時使用self.stuff =,我會使用前者,如果你只有簡單的任務,如果你的類很簡單,並會朝後移動,如果你的要求可能會變得更加複雜的問題。還有很多其他的原因,但它更像一個風格問題。

+0

我相信那些實際上**不是**相等。第一個定義了一個*實例方法*'stuff ='。第二個定義了一個名爲'stuff ='的'Child'的*類方法*。 –

+0

@ChrisRice:的確,我修正了這個問題。 –

+0

謝謝Chris/Marc-André... – Peter