Ruby變數和常數

Ruby變數和常數

Ruby變數和常數可以通過區分Ruby變數名的首位字元來確定它是局部變數、實例變數、類變數、全局變數還是常數。通常情況下,變數名的第二位字元以後是數字、字母或下劃線,但有的內部變數名比較特殊,如“'$'+1個符號”(請參考內部變數)。變數名長度只受記憶體大小的限制。

局部變數,實例變數,全局變數,常數,

局部變數

例:
foobar
若標識符首位是小寫字母或“_”,則該標識符就是局部變數或方法調用。在局部變數的作用域(類、模組、方法的定義部分)內,若對一個首位是小寫字母的標識符進行首次賦值的話,也就意味著聲明了一個屬於該作用域的局部變數。若引用尚未被聲明的標識符的話,就會被解釋成一個無參數的方法調用。
局部變數的作用域起始於聲明處,結束於該聲明所在的塊、方法定義、類/模組定義的結尾。隨著塊的消亡,局部變數也將壽終正寢(頂層局部變數則一直持續到程式終結),但也有例外。若塊已經變成過程對象的話,則局部變數將一直持續到該過程對象終結為止。若多個過程對象引用同一個作用域的話,局部變數將被這些對象所共享。
#(A)的部分位於作用域之外
2.times{
pdefined?(v)#(A)
v=1#從(開始聲明)起
pv#到(塊的終結)是v的作用域
}
#=>nil
1
nil"local-variable"
pv#=>nil
若使用了-K選項的話就可以使用日語標識符,日語標識符被當作局部變數處理。實際上,我們並不推薦您這樣做。

實例變數

例:
@foobar
以@開始的變數是實例變數,它屬於特定的對象。可以在類或子類的方法中引用實例變數。若引用尚未被初始化的實例變數的話,其值為nil。
類變數
例:
classFoo
@@foo=1
defbar
puts@@foo
end
end
以@@開始的變數是類變數。在類的定義中定義類變數,可以在類的特殊方法、實例方法等處對類變數進行引用/賦值。
類變數與常數的區別如下。
可以重複賦值(常數則會發出警告)
不能在類的外部直接引用(在繼承類中則可以引用/賦值)
類變數與類的實例變數的區別如下。
可在子類中引用/賦值
可在實例方法中引用/賦值
可以把類變數看作一種被類、子類以及它們的實例所共享的全局變數
classFoo
@@foo=1
end
classBar2
end
classBaz3
end
模組中定義的類變數(模組變數)被所有包含該模組的類所共享。
moduleFoo
@@foo=1
end
classBar
includeFoo
p@@foo+=1#=>2
end
classBaz
includeFoo
p@@foo+=1#=>3
end

全局變數

例:
$foobar
$/
以$開始的變數是全局變數,可以在程式的任何地方加以引用(因此需要特別留意)。全局變數無需變數聲明。引用尚未初始化的全局變數時,其值為nil。
偽變數
除普通的變數之外,還有一種叫做偽變數的特殊變數。
self
當前方法的執行主體
nil
NilClass類的唯一實例
true
TrueClass類的唯一實例
false
FalseClass類的唯一實例。nil和false表示“偽”。
__FILE__
當前源檔案名稱
__LINE__
當前源檔案中的行號
偽變數的值不可改變,若對偽變數賦值將引發語法錯誤。

常數

例:
FOOBAR
以大寫字母([A-Z])開始的標識符是常數.常數的定義(和初始化)由賦值過程完成.不能在方法中對常數進行定義.若對已定義的常數進行賦值的話,會出現警告信息.若引用未定義的常數的話,則會引發NameError異常.
可以在下列地方引用常數,如,定義常數的類/模組的定義句(也包括方法正文以及嵌套類/模組的定義句)中,繼承該類的子類中,以及包含模組的類/模組中等等.在類定義之外(頂層)定義的常數屬於Object.
例:
classFoo
FOO='FOO'#定義Foo類的常數FOO(Foo::FOO)
end
classBar"FOO"
classBaz
#雖然嵌套類與該類間不存在繼承關係
#但還是可以直接引用嵌套外部的常數
pBAR#=>"BAR"
end
end
另外,在類定義表達式生成類對象的同時,還會將類對象賦值給一個與該類同名的常數.從語法上講,引用類名也就是引用該常數.
classC
end
pC#=>C
若想在外部訪問類或模組中的常數時,要使用"::"操作符.若想準確地訪問Object類中的常數(頂層的常數)時,也需要也使用"::"操作符,但操作符左邊為空.另外,不能使用該操作符對常數進行賦值.
ruby1.8特性:可以使用"::"對常數進行賦值.
例:
moduleM
I=35
classC
end
end
pM::I#=>35
pM::C#=>M::C
p::M#=>M
M::NewConst=777#error-->parseerror
引用常數的優先順序
若在父類和嵌套外側存在同名常數時,會先引用嵌套外側的常數.也就是說,引用常數時會先搜尋嵌套關係的外側,然後才會按照繼承關係向上搜尋.
例:
classFoo
CONST='Foo'
end
classBar
CONST='Bar'
classBaz"Bar"外側的常數
#此時,若不顯式地指定父類中的常數的話,則無法找到該常數
pFoo::CONST#=>"Foo"
end
end
一般認為頂層常數定義並不是位於嵌套外側,所以在搜尋了繼承關係之後才能找到它.可見頂層常數的優先度很低.
例:
classFoo
CONST='Foo'
end
CONST='Object'
classBar"Foo"
end
#若能明顯看出是嵌套關係的話,按規則來說
#首先搜尋到的是Object的常數(位於嵌套外側)
classObject
classBar"Object"
end
end
若對與父類常數同名的常數進行賦值的話,則意味著在該類中定義一個新常數,而並不會對父類常數進行賦值.
例:
classFoo
CONST='Foo'
end
classBar"Foo"
CONST='Bar'#*定義*Bar的常數CONST
pCONST#=>"Bar"(Foo::CONST被禁止了)
pFoo::CONST#=>"Foo"(若使用::的話就可以了)
end

相關詞條

熱門詞條

聯絡我們