?
このドキュメントでは、 php中國語ネットマニュアル リリース
您可以通過區(qū)分Ruby變量名的首位字符來確定它是局部變量、實(shí)例變量、類變量、全局變量還是常數(shù)。通常情況下,變量名的第二位字符以后是數(shù)字、字母或下劃線,但有的內(nèi)部變量名比較特殊,如“'$'+1個符號”(請參考內(nèi)部變量)。變量名長度只受內(nèi)存大小的限制。
例:
foobar
若標(biāo)識符首位是小寫字母或“_”,則該標(biāo)識符就是局部變量或方法調(diào)用。在局部變量的作用域(類、模塊、方法的定義部分)內(nèi),若對一個首位是小寫字母的標(biāo)識符進(jìn)行首次賦值的話,也就意味著聲明了一個屬于該作用域的局部變量。若引用尚未被聲明的標(biāo)識符的話,就會被解釋成一個無參數(shù)的方法調(diào)用。
局部變量的作用域起始于聲明處,結(jié)束于該聲明所在的塊、方法定義、類/模塊定義的結(jié)尾。隨著塊的消亡,局部變量也將壽終正寢(頂層局部變量則一直持續(xù)到程序終結(jié)),但也有例外。若塊已經(jīng)變成過程對象的話,則局部變量將一直持續(xù)到該過程對象終結(jié)為止。若多個過程對象引用同一個作用域的話,局部變量將被這些對象所共享。
# (A)的部分位于作用域之外 2.times { p defined?(v) # (A) v = 1 # 從(開始聲明)起 p v # 到(塊的終結(jié))是 v 的作用域 } # => nil 1 nil <- 請注意這里是 nil 1
即使聲明部分未被執(zhí)行仍將有效。
v = 1 if false # 雖未賦值,但聲明有效 p defined?(v) # => "local-variable" p v # => nil
若使用了 -K 選項的話就可以使用日語標(biāo)識符,日語標(biāo)識符被當(dāng)作局部變量處理。實(shí)際上,我們并不推薦您這樣做。
例:
@foobar
以@開始的變量是實(shí)例變量,它屬于特定的對象??梢栽陬惢蜃宇惖姆椒ㄖ幸脤?shí)例變量。若引用尚未被初始化的實(shí)例變量的話,其值為nil。
例:
class Foo @@foo = 1 def bar puts @@foo end end
以@@開始的變量是類變量。在類的定義中定義類變量,可以在類的特殊方法、實(shí)例方法等處對類變量進(jìn)行引用/賦值。
類變量與常數(shù)的區(qū)別如下。
類變量與類的實(shí)例變量的區(qū)別如下。
可以把類變量看作一種被類、子類以及它們的實(shí)例所共享的全局變量。
class Foo @@foo = 1 end class Bar < Foo p @@foo += 1 # => 2 end class Baz < Bar p @@foo += 1 # => 3 end
模塊中定義的類變量(模塊變量)被所有包含該模塊的類所共享。
module Foo @@foo = 1 end class Bar include Foo p @@foo += 1 # => 2 end class Baz include Foo p @@foo += 1 # => 3 end
例:
$foobar $/
以$開始的變量是全局變量,可以在程序的任何地方加以引用(因此需要特別留意)。全局變量無需變量聲明。引用尚未初始化的全局變量時,其值為 nil。
除普通的變量之外,還有一種叫做偽變量的特殊變量。
self
當(dāng)前方法的執(zhí)行主體
nil
NilClass類的唯一實(shí)例
true
TrueClass類的唯一實(shí)例
false
FalseClass類的唯一實(shí)例。nil 和 false 表示“偽”。
__FILE__
當(dāng)前源文件名
__LINE__
當(dāng)前源文件中的行號
偽變量的值不可改變,若對偽變量賦值將引發(fā)語法錯誤。
例:
FOOBAR
以大寫字母([A-Z])開始的標(biāo)識符是常數(shù).常數(shù)的定義(和初始化)由賦值過程完成.不能在方法中對常數(shù)進(jìn)行定義.若對已定義的常數(shù)進(jìn)行賦值的話,會出現(xiàn)警告信息.若引用未定義的常數(shù)的話,則會引發(fā)NameError異常.
可以在下列地方引用常數(shù),如,定義常數(shù)的類/模塊的定義句(也包括方法正文以及嵌套類/模塊的定義句)中,繼承該類的子類中,以及包含模塊的類/模塊中等等.在類定義之外(頂層)定義的常數(shù)屬于Object.
例:
class Foo FOO = 'FOO' # 定義Foo類的常數(shù)FOO(Foo::FOO) end class Bar < Foo BAR = 'BAR' # 定義Bar類的常數(shù)BAR(Bar::BAR) # 可直接引用父類的常數(shù) p FOO # => "FOO" class Baz # 雖然嵌套類與該類間不存在繼承關(guān)系 # 但還是可以直接引用嵌套外部的常數(shù) p BAR # => "BAR" end end
另外,在類定義表達(dá)式生成類對象的同時,還會將類對象賦值給一個與該類同名的常數(shù).從語法上講,引用類名也就是引用該常數(shù).
class C end p C # => C
若想在外部訪問類或模塊中的常數(shù)時,要使用"::"操作符.若想準(zhǔn)確地訪問Object類中的常數(shù)(頂層的常數(shù))時,也需要也使用"::"操作符,但操作符左邊為空.另外,不能使用該操作符對常數(shù)進(jìn)行賦值.
ruby 1.8 特性: 可以使用"::"對常數(shù)進(jìn)行賦值.
例:
module M I = 35 class C end end p M::I #=> 35 p M::C #=> M::C p ::M #=> M M::NewConst = 777 # error--> parse error
若在父類和嵌套外側(cè)存在同名常數(shù)時,會先引用嵌套外側(cè)的常數(shù).也就是說,引用常數(shù)時會先搜索嵌套關(guān)系的外側(cè),然后才會按照繼承關(guān)系向上搜索.
例:
class Foo CONST = 'Foo' end class Bar CONST = 'Bar' class Baz < Foo p CONST # => "Bar" 外側(cè)的常數(shù) # 此時,若不顯式地指定父類中的常數(shù)的話,則無法找到該常數(shù) p Foo::CONST # => "Foo" end end
一般認(rèn)為頂層常數(shù)定義并不是位于嵌套外側(cè),所以在搜索了繼承關(guān)系之后才能找到它.可見頂層常數(shù)的優(yōu)先度很低.
例:
class Foo CONST = 'Foo' end CONST = 'Object' class Bar < Foo p CONST # => "Foo" end # 若能明顯看出是嵌套關(guān)系的話,按規(guī)則來說 # 首先搜索到的是Object的常數(shù)(位于嵌套外側(cè)) class Object class Bar < Foo p CONST # => "Object" end end
若對與父類常數(shù)同名的常數(shù)進(jìn)行賦值的話,則意味著在該類中定義一個新常數(shù),而并不會對父類常數(shù)進(jìn)行賦值.
例:
class Foo CONST = 'Foo' end class Bar < Foo p CONST # => "Foo" CONST = 'Bar' # *定義*Bar的常數(shù)CONST p CONST # => "Bar" (Foo::CONST 被屏蔽了) p Foo::CONST # => "Foo" (若使用:: 的話就可以了) end