2011-03-11 45 views
5

我正在使用Ruby on Rails 3,我想知道在什麼情況下應該使用實例變量而不是其他變量類型,以及是否存在安全原因。在什麼情況下我應該使用實例變量而不是其他變量類型?

實施例:

# Using an instance variable 
@accounts = Account.find(...) 

# Using a "local"\"normal" variable 
account = Account.find(...) 
+0

類變量就像'@@ accounts'。 '@ accounts'是一個實例變量。 –

+0

你給出的第一個例子是一個實例變量,而不是一個類變量。第二個是局部變量。您是否特指控制器,模型或一般的Ruby類? –

+0

@LBg,@潘Thomakos - 對不起,是我的錯。我不是這方面的專家。 – user502052

回答

9

一般的實例變量是本地和持久對象的實例內,而局部變量僅本地和持續的功能/對象/塊範圍內。例如:

class User 
    def name 
    @name 
    end 

    def name= name 
    @name = name 
    end 
end 

def greet user 
    name = user.name || 'John' 
    p "Hi, my name is #{name}" 
end 

user = User.new 
greet user 
=> 'Hi, my name is John' 
name 
=> NameError: undefined local variable or method 'name' for main:Object 
user.name = "Mike" 
greet user 
=> 'Hi, my name is Mike' 
@name 
=> nil 

在greet函數name是僅在該函數內定義一個局部變量。名稱變量在函數name = user.name || 'John'的第一行上設置,但其值不會保留在函數外。當您嘗試呼叫name時,您將得到一個NameError,因爲名稱只在greet函數中被定義爲局部變量。

@name對於User類的用戶實例是本地的。當你嘗試在該環境之外調用它時,你會得到nil。這是本地變量和實例變量之間的區別,實例變量如果尚未定義則返回nil,而本地非實例變量則引發錯誤。

請注意,儘管這兩種變量類型都是特定上下文的局部變量。 @name在用戶實例中定義,所以當您撥打user.name時,您正在調用用戶實例中的名稱函數,其中定義了@namename僅在問候函數中定義,所以當您撥打p "Hi, my name is #{name}"時,您可以獲得name的值,因爲您處於定義範圍內。

+0

@ Davy8迴應了我。 – user502052

+2

你能解釋一下爲什麼你要在你的getter方法中使用@name而不是簡單的局部變量名?由於實例變量和局部變量在其上下文中都是有效的,爲什麼要區分這兩者? –

9

@潘的回答給出了他們之間差異的一個很好的解釋。

一般情況下(幾乎任何語言),您想要在所需的最小範圍內定義變量。所以,如果你不需要在函數調用中保持某些東西,那麼將其設置爲本地。

如果您需要一個變量在函數調用中持久保存,但僅限於特定類實例,請將其變爲實例變量。

如果您需要一個該類的每個實例之間共享的東西,那麼使用類變量,但是這方面的需要應該是比較少見,所以仔細想想你是否真的需要一個類變量。 (免責聲明:我只用Ruby玩了大約2周,所以這大多是一個語言不可知的答案,但我非常肯定它適用於Ruby。如果我錯了,請隨時糾正我。 )

相關問題