閑云無衣
          無衣的筆記
          Ruby有三類變量,一種常量和兩種嚴格意義上的偽變量(pseudo-variables).變量和常量都沒有類型.雖然無類型變量存在一定的缺點,但卻有更多的優點并很好的符合Ruby快速簡便(quick?and?easy)的哲學精神.

          在大多數語言里,變量都必須指定其類型,可更改性(是不是個常數)和范圍;由于類型的不存在,剩下的東西也可由變量名字很快確定(你馬上會看見),在Ruby里我們不需要變量聲明.

          由首字母標識符將其分類:

          $??????????全局變量??
          @??????????實變量?
          [a-z]??????局部變量?
          [A-Z]??????常量?

          唯一的例外是Ruby的偽變量:self,它永遠指向當前正執行著的對象或未初始化變量的空值(meaningless?value)nil.雖然這兩者 的命名都像是局部變量,但?self?卻是個由解釋器把持的全局變量,而?nil?實際上是個常量.既然只有這兩種意外,他們并不會過多的干擾我們.

          你并能向?self?或?nil?賦值.下面的例子中,?main作為?self?的值,指向最高層的對象:

          ruby>?self
          ???main
          ruby>?nil
          ???nil

          全局變量:

          全局變量由$開頭.它們可以在程序的任何位置訪問到.在初始化前,全局變量有一個特殊的值?nil.
          ruby>?$foo
          ???nil
          ruby>?$foo?=?5
          ???5
          ruby>?$foo
          ???5


          應謹慎使用全局變量.由于在任何地方都可以被寫因此他們相當危險.濫用全局變量會導致很難隔離臭蟲;同時也視為程序的設計未經嚴格考慮.當你發現必須要使用全局變量時,記得給它一個不會在其它地方一不小心就用到的描述性名字(像上面那樣叫$foo可能不是一個好想法).

          全局變量的好處是其可以被跟蹤;你可以做一個當變量值改變時被調用的過程.
          ruby>?trace_var?:$x,?proc{print?"$x?is?now?",?$x,?"\n"}
          ???nil
          ruby>?$x?=?5
          $x?is?now?5
          ???5

          當一個全局變量(改變時)作為一個過程的激發器,我們也管它叫活動變量(active?variable).比如說,它可用于保持GUI顯示的更新.

          這里列出了一些以$打頭并跟單個字符的特殊變量.比如,$$包含了Ruby解釋器的進程id,它是只讀的.這里是主要的系統變量以及它們的含義(細節可在Ruby的參考手冊中查到):

          $!??最近一次的錯誤信息?
          $@??錯誤產生的位置?
          $_??gets最近讀的字符串??
          $.??解釋器最近讀的行數(line?number)?
          $&??最近一次與正則表達式匹配的字符串?
          $~??作為子表達式組的最近一次匹配??
          $n??最近匹配的第n個子表達式(和$~[n]一樣)??
          $=??是否區別大小寫的標志??
          $/??輸入記錄分隔符?
          $\??輸出記錄分隔符?
          $0??Ruby腳本的文件名?
          $*??命令行參數?
          $$??解釋器進程ID?
          $???最近一次執行的子進程退出狀態?

          上面的?$_?和?$~?都有作用范圍.它們的名字暗示其為全局的,但它們一般都是這樣用的,關于它們的命名有歷史上的原因。

          實例變量:

          一個實例變量由@開頭,它的范圍限制在?self?對象內.兩個不同的對象,即使屬于同一個類,也可以擁有不同值的實變量.從對象外部來看,實變量不能改變 甚至觀察(比如,?Ruby的實變量從來不是公用的),除非方法由程序員明確聲明.像全局變量一樣,實變量在初始前的值是nil.

          Ruby的實例變量用不著聲明.這暗含著對象的彈性結構.實際上,每個實變量都是在第一次出現時動態加入對象的.
          ruby>?class?InstTest
          ????|???def?set_foo(n)
          ????|?????@foo?=?n
          ????|???end
          ????|???def?set_bar(n)
          ????|?????@bar?=?n
          ????|???end
          ????|?end
          ???nil
          ruby>?i?=?InstTest.new
          ???#<InstTest:0x83678>
          ruby>?i.set_foo(2)
          ???2
          ruby>?i
          ???#<InstTest:0x83678?@foo=2>
          ruby>?i.set_bar(4)
          ???4
          ruby>?i
          ???#<InstTest:0x83678?@foo=2,?@bar=4>

          注意上例中直到調用了?set_bar方法?i?才報告?@bar?的值.

          局部變量:

          局部變量由小寫字母或下劃線(_)開頭.局部變量不像全局和實變量一樣在初始化前含nil值.
          ruby>?$foo
          ???nil
          ruby>?@foo
          ???nil
          ruby>?foo
          ERR:?(eval):1:?undefined?local?variable?or?method?`foo'?for?main(Object)

          對局部變量的第一次賦值做的很像一次聲明.如果你指向一個未初始化的局部變量,Ruby解釋器會認為那是一個方法的名字;正如上面所見錯誤

          信息的.

          一般的,局部變量的范圍會是
          • proc{...}?

          • loop{...}?

          • def...end?

          • class...end?

          • module...end?

          • 整個程序(除非符合上面某個條件)

          下面的例子,define?是一個檢查標識符是否已定義的操作符.如果已定義它將返回標識符的描述,否則返回nil.正如你所見的,bar的范圍是

          loop的局部變量;當loop退出時,bar無定義.

          ruby>?foo?=?44;?print?foo,?"\n";?defined??foo
          44
          ???"local-variable"
          ruby>?loop{bar=45;?print?bar,?"\n";?break};?defined??bar
          45
          ???nil

          一個范圍內的過程對象共享這個范圍內的局部變量.這里,局部變量?bar?由?main?和過程對象?p1,?p2共享:
          ruby>?bar=0
          ???0
          ruby>?p1?=?proc{|n|?bar=n}
          ???#<Proc:0x8deb0>
          ruby>?p2?=?proc{bar}
          ???#<Proc:0x8dce8>
          ruby>?p1.call(5)
          ???5
          ruby>?bar
          ???5
          ruby>?p2.call
          ???5

          注意開始的"bar=0"不能省略;此賦值允許bar的范圍被?p1和?p2共享.不然?p1,?p2?將會分別生成并處理它們自己的局部變量?bar,?調用?p2?

          也將導致"未定義局部變量或方法"錯誤.

          過程對象的強大在于它們能被作為參數傳遞:共享的局部變量即使傳遞出原范圍也仍然有效.
          ruby>?def?box
          ????|???contents?=?15
          ????|???get?=?proc{contents}
          ????|???set?=?proc{|n|?contents?=?n}
          ????|???return?get,?set
          ????|?end
          ???nil
          ruby>?reader,?writer?=?box
          ???[#<Proc:0x40170fc0>,?#<Proc:0x40170fac>]?
          ruby>?reader.call
          ???15
          ruby>?writer.call(2)
          ???2
          ruby>?reader.call
          ???2


          Ruby對待范圍的辦法相當聰明.顯然,上面例子里?contents?變量是由?reader?和?writer?共享的.我們也可以像上面那樣創造多對使用box的

          reader-writer;每一對共享一個?contents?變量,對之間不相干擾.

          ruby>?reader_1,?writer_1?=?box
          ???[#<Proc:0x40172820>,?#<Proc:0x4017280c>]
          ruby>?reader_2,?writer_2?=?box
          ???[#<Proc:0x40172668>,?#<Proc:0x40172654>]
          ruby>?writer_1.call(99)
          ???99
          ruby>?reader_1.call
          ???99
          ruby>?reader_2.call
          ???15

          類常量:

          一個常量由大寫字母開頭.它應最多被賦值一次.在Ruby的當前版本中,常量的再賦值只會產生警告而不是錯誤(non-ANSI版的eval.rb不會報告這一警告)
          ruby>fluid=30
          ???30
          ruby>fluid=31
          ???31
          ruby>Solid=32
          ???32
          ruby>Solid=33
          ???(eval):1:?warning:?already?initialized?constant?Solid
          ???33

          常量可以定義在類里,但不像實變量,它們可以在類的外部訪問.
          ruby>?class?ConstClass
          ????|???C1=101
          ????|???C2=102
          ????|???C3=103
          ????|???def?show
          ????|?????print?C1,"?",C2,"?",C3,"\n"
          ????|???end
          ????|?end
          ???nil
          ruby>?C1
          ERR:?(eval):1:?uninitialized?constant?C1
          ruby>?ConstClass::C1
          ???101
          ruby>?ConstClass.new.show
          101?102?103
          ???nil

          常量也可以定義在模塊里.

          ruby>?module?ConstModule
          ????|???C1=101
          ????|???C2=102
          ????|???C3=103
          ????|???def?showConstants
          ????|?????print?C1,"?",C2,"?",C3,"\n"
          ????|???end
          ????|?end
          ???nil
          ruby>?C1
          ERR:?(eval):1:?uninitialized?constant?C1
          ruby>?include?ConstModule
          ???Object
          ruby>?C1
          ???101
          ruby>?showConstants
          101?102?103
          ???nil
          ruby>?C1=99??#?not?really?a?good?idea
          ???99
          ruby>?C1
          ???99
          ruby>?ConstModule::C1??#?the?module's?constant?is?undisturbed?...
          ???101
          ruby>?ConstModule::C1=99?
          ERR:?(eval):1:?compile?error
          (eval):1:?parse?error
          ConstModule::C1=99
          ????????????????^
          ruby>?ConstModule::C1??#?..?regardless?of?how?we?tamper?with?it.
          ???101
          posted on 2007-02-08 14:10 無衣 閱讀(1153) 評論(0)  編輯  收藏 所屬分類: rails
           
          主站蜘蛛池模板: 西宁市| 普定县| 湘乡市| 昂仁县| 即墨市| 连南| 林甸县| 长顺县| 镇安县| 米脂县| 灌南县| 开远市| 拜城县| 疏勒县| 麦盖提县| 金阳县| 和平县| 锦州市| 西吉县| 田阳县| 于都县| 秦安县| 荣成市| 卓资县| 格尔木市| 宁国市| 都兰县| 宁安市| 恩施市| 天柱县| 隆化县| 安溪县| 成都市| 九寨沟县| 闸北区| 伊春市| 奉化市| 辽阳县| 五原县| 新乐市| 吕梁市|