2012-10-02 14 views
1

當我開始學習Ruby時,我從Michael Hartl出色的Rails Tutorial開始。我剛剛重新訪問了教程,並注意到示例應用程序代碼的部分內容已被修改。在認證章節中,更改了兩種方法:添加self關鍵字有什麼不同?

# SessionsHelper 
def sign_in(user) 
    ... 
    self.current_user = user 
end 

def sign_out 
    self.current_user = nil 
    ... 
end 

以前,關鍵字self被省略。但該應用程序工作。所以,如果它沒有損壞,爲什麼要修復它? self增加了什麼值,它爲什麼被使用?

我知道self定義了類方法,而不是實例方法。在模型中,使用self可以讓我們直接引用對象的屬性。但是我不能把這些點聯繫起來,看看它是如何用於幫手的。我以前在控制器中看過它,我不明白爲什麼我們想在那裏使用它。

+1

如果這個工作是不帶'self'關鍵字,那麼他們必須一直使用實例變量(B/C這個調用setter方法,但沒有自我,它會設置一個局部變量)。這些不是一回事,而IMO,使用設置方法比實例變量好得多(b/c設置ivar直接意味着你已經知道它的實現,但是調用setter將這些知識僅包含在一個方法中)。 –

+1

@JoshuaCheek:不一定,可能有'attr_accessor:current_user'或者一個顯式方法'def current_user =(new_user)',並且相同的語法是有效的。 – maerics

+0

確實有一種方法(在新版本和舊版本中):'def current_user =(user)@current_user = user end' – Mohamad

回答

4

[編輯]

很可能是本教程的原始部分是完全錯誤的。忽略「自我」接收器會導致方法爲方法局部變量「current_user」分配一個值,而不會產生其他影響。

我在下面的原始答案是不正確的,應該忽略(因爲寫作者方法foo=(x)無法在沒有接收器的情況下調用,其他方法也是如此)。

[原創不正確回答下面]

之所以使用「自我」接收器可能是爲了清楚起見。

如果省略了「自我」,那麼,對未經訓練的眼睛,它看起來像你只是分配「用戶」變量名爲「CURRENT_USER」沒有其他效果的新變量。有經驗的Ruby專家知道,如果在對象實例上有一個名爲「current_user」的方法,那麼它將被調用,而不是僅僅創建和分配一個新變量,但是這個細節很容易被忽略,特別是如果該方法被繼承或者未被聲明當前類定義部分。

明確使用「self」關鍵字明確指出您正在調用此對象實例的方法。

+0

真的嗎?如果''current_user'在分配的左邊部分沒有'self'使用,Ruby將創建局部變量而不是調用'current_user'方法(即使定義了'current_user =')。這是我在這裏想念的東西嗎? –

+0

-1。這顯然是錯誤的。 'foo = bar' * always *賦值給局部變量'foo'。它絕不會*在任何情況下都不會發送'foo ='消息。決不。如果您想調用寫入器方法,您總是*必須*使用明確的接收器。因爲這個原因,「私人」方法甚至有一個例外。 ('private'方法只能在沒有明確接收者的情況下被調用,編寫者只能用明確的接收者調用,因此如果不存在異常,則不可能調用私人編寫器。) –

+0

啊,有趣。也許這是1.8的行爲?我還證實,在1.9這是*不是*的情況。 – maerics

1
class User 
    attr_accessor :current_user 

    def sign_in_1 
    # Assigning local variable here 
    current_user = "Foo" 
    end 

    def sign_in_2 
    # Calling accessor method 
    self.current_user = "Bar" 
    end 
end 

u = User.new 
u.sign_in_1 
p u.current_user #=> nil 
u.sign_in_2 
p u.current_user #=> "Bar" 
相關問題