2011-09-08 42 views
3

在邁克爾·哈特爾的教程,他有一個module SessionsHelper,其中有一個叫current_user=方法,它接受一個參數,並將其分配給@current_user。然後,他使用current_user = User.first這樣的行在他的程序中以其他各種方法調用此方法。Rails - 在末尾使用等號的方法?

我的問題是,我們如何知道current_user=方法被調用的話 - 在我看來,那什麼會實際上發生的是一個叫current_user當場創建新的變量,鑑於User.first值,那麼當函數關閉那個變量就會死掉。

我還測試了這款簡單地通過創建下面的代碼:

def x= val 
puts "method called" 
end 

x = 46 
puts x 

這段代碼簡單地打印46在屏幕上 - 功能x=永遠不會被調用。那麼在Michael Hartl的教程中做什麼current_user=方法,以及他如何使該函數被調用?

回答

4

這是因爲Ruby把表達式看作簡單變量的簡單變量。你可以看到這個代碼:

def x 
    10 
end 

print x  #=> 10 
x = 5 
print x  #=> 5 
print x() #=> 10 
print self.x #=> 10 

這是一樣的情況。看:

def x=(a) 
    print a 
end 

x = 8  #=> Variable 'x' assigned to 8 
x=(8)  #=> The same 

self.x = 8 #=> Function called 

還記得分配功能(如最後一個)無法返回任何值,返回值將始終是最後一個參數。

def x=(a) 
    return a+1 
end 

var = (self.x = 8) #=> Function called; Variable 'var' assigned to 8 
0

從Ruby開發者的一個常見的抱怨是,有時很難,當你指的是變量或方法來告訴。這裏試圖用我公認的有限理解來解釋它是如何工作的。

Ruby沒有的概念「對象屬性」,至少不會以同樣的方式爲大多數其他語言。如果你的對象有一個名爲@current_user的實例變量,這是完全不能訪問該對象以外的任何東西(instance_variable_get和instance_variable_set一邊 - 此處有怪物)的唯一途徑獲得或從外部設定@current_user是定義「CURRENT_USER 「和/或」current_user =「方法(或」attr_accessor:current_user「,它做同樣的事情)。

所以當你調用」obj.current_user = user「時,一些語法糖被調用,Ruby知道你只是調用current_user =方法。畢竟,由於您無法從外部訪問實例變量,因此沒有其他可能的意思。

當你的對象中,你需要調用CURRENT_USER =與「self.current_user =用戶」。否則你是對的,它只會創建一個局部變量。而且,由於Ruby在其OO設計中非常一致,這正是您的示例中發生的情況。 「x = 5」只是創建一個局部變量,但「self.x = 5」將調用x =方法。

0

注意:如其他答案所示,x =和self.x =執行不同的功能。

內SessionsHelper的範圍內,我相信常見的用法是使用模塊作爲一類混入。

考慮以下幾點:

class Foo 
    include SessionsHelper 
    def foo_current_user 
    puts 'foo' + current_user 
    end 
end 

class Bar 
    include SessionsHelper 
    def bar_current_user 
    puts 'bar' + current_user 
    end 
end 

他模塊從而允許你做Foo.new.foo_current_user()Bar.new.bar_current_user()在堅持DRY原則。

它將值存儲到兩個類中的實例變量@current_user中。在課堂之外,mixin模塊可能沒有多大意義。