我正在使用Ruby on Rails 3,我想知道在什麼情況下應該使用實例變量而不是其他變量類型,以及是否存在安全原因。在什麼情況下我應該使用實例變量而不是其他變量類型?
實施例:
# Using an instance variable
@accounts = Account.find(...)
# Using a "local"\"normal" variable
account = Account.find(...)
我正在使用Ruby on Rails 3,我想知道在什麼情況下應該使用實例變量而不是其他變量類型,以及是否存在安全原因。在什麼情況下我應該使用實例變量而不是其他變量類型?
實施例:
# Using an instance variable
@accounts = Account.find(...)
# Using a "local"\"normal" variable
account = Account.find(...)
一般的實例變量是本地和持久對象的實例內,而局部變量僅本地和持續的功能/對象/塊範圍內。例如:
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
時,您正在調用用戶實例中的名稱函數,其中定義了@name
。 name
僅在問候函數中定義,所以當您撥打p "Hi, my name is #{name}"
時,您可以獲得name
的值,因爲您處於定義範圍內。
@ Davy8迴應了我。 – user502052
你能解釋一下爲什麼你要在你的getter方法中使用@name而不是簡單的局部變量名?由於實例變量和局部變量在其上下文中都是有效的,爲什麼要區分這兩者? –
@潘的回答給出了他們之間差異的一個很好的解釋。
一般情況下(幾乎任何語言),您想要在所需的最小範圍內定義變量。所以,如果你不需要在函數調用中保持某些東西,那麼將其設置爲本地。
如果您需要一個變量在函數調用中持久保存,但僅限於特定類實例,請將其變爲實例變量。
如果您需要一個該類的每個實例之間共享的東西,那麼使用類變量,但是這方面的需要應該是比較少見,所以仔細想想你是否真的需要一個類變量。 (免責聲明:我只用Ruby玩了大約2周,所以這大多是一個語言不可知的答案,但我非常肯定它適用於Ruby。如果我錯了,請隨時糾正我。 )
類變量就像'@@ accounts'。 '@ accounts'是一個實例變量。 –
你給出的第一個例子是一個實例變量,而不是一個類變量。第二個是局部變量。您是否特指控制器,模型或一般的Ruby類? –
@LBg,@潘Thomakos - 對不起,是我的錯。我不是這方面的專家。 – user502052