ruby語法基礎教程_第1頁
ruby語法基礎教程_第2頁
ruby語法基礎教程_第3頁
ruby語法基礎教程_第4頁
ruby語法基礎教程_第5頁
已閱讀5頁,還剩83頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Grant Renhyqryq2006年11月24日 前 言 目 錄Ruby語言1Grant Ren1第一部分 Ruby語言基礎8第一章 Ruby語言概述8§1.1 Ruby的歷史8§1.2 Ruby名字的由來8§1.3 Ruby的特點8§1.4 Ruby和Python的比較9第二章 Ruby編程環境9§2.1 Ruby的安裝9§2.1.1 在Windows 95/98/Me/XP上安裝Ruby9§2.1.2 在Linux上安裝Ruby10§2.2 運行Ruby10§2.2.1 使用Ruby10§

2、;2.2.2 使用FreeRIDE和SciTE11§2.2.3 使用fxri13§2.3 Ruby-irb14§2.4 Ruby-ri15§2.5 RubyGems15第三章類與對象17§3.1 類的定義17§3.2 對象,屬性和方法18§3.3 繼承20§3.4 特殊方法與特殊類21§3.5 類變量與類方法23§3.4 存取控制23§3.6 元類25§3.7 Ruby的動態性26§3.8 變量26§3.8.1 局部變量27§3.8.2 實例變量

3、27§3.8.3 類變量27§3.8.4 全局變量28§3.8.5 常量28§3.8 與定義有關的操作29§3.8.1 alias29§3.8.2 undef30§3.8.3 defined?31第四章基本類型33§4.1 Array33§4.2 Hash34§4.3 Number34§4.4 String35§4.5 Range36§4.6 Symbol37§4.7 正則表達式37第五章代碼塊和迭代器38§5.1 代碼塊(Block)38

4、67;5.1.1 什么是代碼塊38§5.1.2 代碼塊與對象39§5.2 迭代器(Iterator)40§5.2.1 什么是迭代器40§5.2.2 使用迭代器40§5.2.3 yield41§5.2.4 編寫自己的迭代器42第六章表達式42§6.1 運算符43§6.2 命令替換44§6.3 賦值運算符44§6.4 并行賦值46§6.5 嵌套賦值47§6.6 其他賦值47§6.7 條件運算47§6.8 case表達式48§6.9 循環49§

5、;6.9.1 Loop49§6.9.2 While50§6.9.3 Until50§6.9.4 Iterator50§6.9.5 For.In51§6.9.6 Break,Redo,Next51§6.9.7 Retry53第七章方法54§7.1 運算符重定義55§7.2 變長參數56§7.3 塊調用56§7.4 方法返回值57第八章模塊59§8.1 名字空間59§8.2 mixin59§8.3 使用mixin60§8.3.1 Comparable60

6、67;8.3.2 Enumerable61§8.3.3 Singleton62§8.4 Require, load和include62第九章異常64§9.1 異常處理64§9.2 定義異常類68§9.3 catch和throw68第十章多任務處理69§10.1 多線程處理69§10.1.1 線程創建69§10.1.2 線程操作70§10.1.3 線程和異常71§10.1.4 線程調度73§10.1.5 線程同步73§10.2 多進程處理79§10.2.1 進程創建7

7、9第十一章基本I/O操作80§11.1 使用Kernel模塊處理I/O操作80§11.2文件處理80§11.3 StringIO81§11.4 Socket82第十二章反射和對象空間82§12.1 ObjectSpace模塊82§12.2 察看類和對象的狀態83§12.3 動態方法調用86§12.3.1 使用send方法86§12.3.2 使用Method類和UnboundMethod類86§12.3.3 使用eval方法88§12.3.4 性能88§12.4 Hook和回調

8、方法89§12.4.1 什么是Hook89§12.4.2 Ruby中的Hook89§11.4.2 回調方法90§12.5 跟蹤程序的運行90§12.5.1 set_trace_func90§12.5.2 trace_var91§12.5.3 caller91§12.5.3 _FILE_,_LINE_和SCRIPT_LINES_92第十三章序列化和YAML92§13.1 序列化的概念92§13.2 使用序列化93§13.2.1 二進制數據保存93§13.2.2 YAML數據保存

9、93§13.3 定制序列化94§13.3.1 二進制數據保存94§13.3.2 YAML數據保存95§13.3 YAML95§13.3.1 集合類型96§13.3.2 單行集合類型99§13.3.3 基本類型99§13.3.4 塊99§13.3.5 別名和錨(Aliases and Anchors)99§13.3.6 文檔99§13.3.7 Ruby中YAML的使用99第十四章安全控制100§14.1 0級101§14.1 1級101§14.2 2級101

10、§14.3 3級101§14.4 4級101第十五章單元測試101§15.1 什么是單元測試101§15.2 Ruby單元測試框架101第二部分內置類與模塊101第一章內置類102§1.1 Array102§1.2 Bignum102§1.3 Binding102§1.4 Class102§1.5 Continuation102§1.6 Dir104§1.7 Exception104§1.8 FalseClass104§1.9 File104§1.10 F

11、ile:Stat104§1.11 Fixnum104§1.12 Float104§1.13 Hash104§1.14 Integer104§1.15 IO104§1.16 MatchData104§1.17 Method104§1.18 Module104§1.19 NilClass104§1.20 Numeric104§1.21 Object104§1.22 Proc105§1.23 Process:Status105§1.24 Range105

12、7;1.25 Regexp105§1.26 String105§1.27 Struct105§1.28 Struct:Tms105§1.29 Symbol105§1.30 Thread105§1.31 ThreadGroup105§1.32 Time105§1.33 TrueClass105§1.34 UnboundMethod105第二章內置模塊106§2.1 Comparable106§2.2 Enumerable106§2.3 Error106§2.4 Fil

13、eTest106§2.5 GC106§2.6 Kernel106§2.7 Marshal106§2.8 Math106§2.9 ObjectSpace106§2.10 Process106§2.11 Process:GID106§2.12 Process:Sys106§2.13 Process:UID106§2.14 Signal106第三部分 Ruby語言總結107附錄110§1 術語對照110第一部分 Ruby語言基礎第一章 Ruby語言概述§1.1Ruby的歷史Ruby

14、語言的發明人是日本人松本行弘(Matsumoto Yukihiro),大家親切的稱呼他"Matz"。可能會出乎大家的意料,Ruby并不是一種近年來才誕生的語言,它的歷史可以追溯到1993年,Ruby之父Matz開始對腳本語言感興趣。在通過一些分析和思考之后,Matz認為腳本語言是可以變得很強大和靈活的,于是他準備把腳本語言作為他的發展方向。 和很多人一樣,Matz是一個面向對象程序設計的fans,自然而然他想研究一種支持面向對象程序設計的腳本語言。隨后的一段時間,他到網絡上搜集了一些相關的資料,并且發現了Perl 5,當時Perl 5還沒有發布。通過一段時間了解后,Matz

15、.發現Perl 5這并不是他想的東西,所以他放棄了把Perl當作一個面向對象的腳本語言使用的念頭。隨后Matz轉向了Python,Python是一個解釋型的、面向對象語言,但是Matz發現Python并不能完全算作“面向對象”語言。Matz認為Python是面向對象和過程化程序設計語言(Procedural Programming Language)的混合產物。Matz希望找到的是一種比Perl更強大、比Python更面向對象的語言,但是很遺憾, 這樣的語言當時在地球上并不存在。于是Matz打算自己設計一個全新的編程語言。1993年2月24日是一個值得紀念的日子,在這一天Ruby誕生了。 19

16、95年12月Matz推出了Ruby的第一個版本Ruby 0.95。 在1996年以前,都是Matz.一個人在開發進行Ruby的開發。后來隨著Ruby社區的漸漸形成,很多社區成員給了Matz許多有意義的幫助,包括提交bug和patch等。現在,Ruby像其他開源項目一樣,有自己的開發團隊,任何有能力的個人或團體都可以參與Ruby的開發與進化。§1.2 Ruby名字的由來首先明確一點,Ruby并不是其他單詞的縮寫。受Perl的影響,Matz也想用一種寶石來命名他的新語言,他使用了他的一位同事的生肖石紅寶石。后來,Matz意識到Ruby這個名字十分恰當,首先,在生肖石中,Pearl代表六月

17、,而Ruby代表七月。在字體大小上,Pearl大小是5pt, ruby的大小是5.5pt。所以Ruby這個名字對于一種Perl的后續語言十分合適。§1.3 Ruby的特點Ruby是一種功能強大的面向對象的腳本語言,可以使用它方便快捷地進行面向對象程序設計。與Perl類似,而且Ruby具有強大的文本處理功能,使文本處理變得簡單。此外還可以方便地使用C語言來擴展Ruby的功能。若您曾經“想要一種簡單的面向對象的語言”,或者認為“Perl的功能雖然好用,但它的語法真讓人受不了”,又或者覺得“LISP系列語言的思想不錯,但到處都是括號真讓人討厭,最起碼算式應該按照通常的樣式書寫”。那么,Ru

18、by或許能讓您滿意。歸納起來,Ruby有以下優點:l 解釋型執行,方便快捷Ruby是解釋型語言,其程序無需編譯即可執行。l 語法簡單、優雅語法比較簡單,類似Algol系語法。l 完全面向對象Ruby從一開始就被設計成純粹的面向對象語言,因此所有東西都是對象,例如整數等基本數據類型。l 內置正則式引擎,適合文本處理Ruby支持功能強大的字符串操作和正則表達式檢索功能,可以方便的對字符串進行處理。l 自動垃圾收集具有垃圾回收(Garbage Collect,GC)功能,能自動回收不再使用的對象。不需要用戶對內存進行管理。l 跨平臺和高度可移植性Ruby支持多種平臺,在Windows, Unix,

19、Linux, MacOS上都可以運行。Ruby程序的可移植性非常好,絕大多數程序可以不加修改的在各種平臺上加以運行。l 有優雅、完善的異常處理機制Ruby提供了一整套異常處理機制,可以方便優雅地處理代碼處理出錯的情況。l 擁有很多高級特性Ruby擁有很多高級特性,例如操作符重載、Mix-ins、特殊方法等等,是用這些特性可以方便地完成各種強大的功能。同時,由于是解釋型語言,Ruby也有下列缺點:l 解釋型語言,所以速度較慢l 靜態檢查比較少§1.4Ruby和Python的比較Python是Ruby的勁敵。其功力深厚,可謂“千年蛇妖”。但matz認為Python的功能仍不完美,不然就不

20、會創造Ruby了。第二章 Ruby編程環境§2.1 Ruby的安裝Ruby支持多種平臺,包括Windows、Linux、各種類UNIX、MacOS X等。§2.1.1在Windows 95/98/Me/XP上安裝Ruby對于使用Windows平臺的用戶,安裝Ruby是相當簡單直接的事情。最方便的方法是使用“One-Click Ruby Installer”。不知你有沒有聽說過SourceForge?SourceForge 是全球最大的開放源代碼軟件開發平臺和倉庫。它集成了很多開放源代碼應用程序,為軟件開發提供了整套生命周期服務。在Ruby世界,也有一個類似的網站,那就是Ru

21、byforge。“One-Click Ruby Installer”是Rubyforge上的一個開源項目,也是Rubyforge上下載量最大的項目之一。這個項目將Ruby語言核心和一系列常用擴展集成到了一起,還包含支持Ruby的免費的IDE工具FreeRIDE和SciTE,除了這些之外還包括幫助文檔,示例代碼,RubyGems包管理器,Fox GUI庫,fxri(Interactive RubyHelp& Console)等。和正如它名字所示,使用它,Ruby安裝變得前所未見的容易。你可以在下面的地址下載到它的最新版本:/projects/ruby

22、installer/§2.1.2在Linux上安裝Ruby在linux下Ruby的安裝要稍微復雜一些,推薦使用源碼編譯的方式安裝,這樣可以保證安裝的是最新版本。首先到ruby主站/en/下載源代碼,下載完畢后解壓到目錄,然后使用以下命令:./configure./make; make install執行上面的命令需要root權限,默認安裝到/usr/local下。你也可以使用“./configure -prefix=自定義路徑”來指定安裝目錄。windows上的ruby one-click installer默認安裝了RubyGems,但

23、在Linux下我們需要手動安裝RubyGems。RubyGems是一個Ruby的包管理器,我們后邊會講到它。首先從Rubyforge下載RubyGems的最近版本,地址如下:/projects/rubygems/解壓RubyGems以后到相應目錄下輸入ruby setup.rb,屏幕上打印一些日志以后會告訴你安裝成功,執行gem -v可以查看gem安裝版本號。§2.2運行Ruby下面,我們將以Windows平臺下的Ruby環境舉例如何運行Ruby。§2.2.1使用Ruby將“Hello World”作為學習計算機語言第一個學寫的程序,現

24、在已經成為一種傳統。該程序最早出現在由Brian Kernighan和Dennis Ritchie寫的經典計算機程序設計教程The C Programming Language。我們來看看Ruby世界的“Hello World”:在Windows中,打開命令行提示符窗口,在提示符上輸入“Ruby”并回車,Ruby解釋器就會運行并等候輸入程序。Ruby可執行文件應該包含在系統搜索路徑內。輸入下面的程序:print "Hello World!"然后按Ctrl+D再按回車鍵,你就會看到Ruby執行程序的輸出結果:你也可以先將代碼保存為文件,然后使用再Ruby解釋器執行:§

25、;2.2.2 使用FreeRIDE和SciTEFreeRIDE是一個支持Ruby語言的免費IDE環境。FreeRIDE本身就是使用Ruby語言開發,它也是Rubyforge上的重要項目之一。可以使用FreeRIDE來編寫調試和執行Ruby代碼,FreeRIDE內置了交互式變成環境和Ruby語言在線幫助,功能十分強大。Scintilla是一個免費的源代碼編輯控件,它完全開放源代碼,并允許用戶自由地用于開源軟件或是商業軟件中。SciTE是用這個控件開發了一個編輯軟件,在“One-Click Ruby Installer”中,SciTE集成了Ruby語言支持,使用起來非常方便。相比FreeRIDE,

26、它的特點就是使用簡單。§2.2.3 使用fxriFxri是一個Ruby交互幫助和控制臺工具。它不僅可作為語言的在線幫助,而且可以用作交互式Ruby解釋器來執行程序。對于學習Ruby語言,fxri是一個非常方便的幫手。不知你有沒有聽說過FoxToolKit,它是相當輕巧的開放源代碼的圖形庫。FXRuby是RubyForge上的一個項目,提供了Ruby語言使用Fox ToolKit的接口。而Fxri正是基于FXRuby開發,Fxri同樣是RubyForge上的項目。這樣你應該可以猜到Fxri名字的由來JFxri同時集成了Ruby-irb和Ruby-ri的功能,有了它,你可以拋開Ruby-

27、irb,Ruby-ri了,但如果你用的不是Windows系統的話,算我沒說J§2.3Ruby-irbRuby-irb是交互式Ruby(Interactive Ruby)的簡稱,用來從標準輸入讀入并執行Ruby代碼的工具,像一個shell。使用命令“irb”進入交互式模式,然后可以象輸入命令行命令一樣輸入Ruby代碼,代碼執行的結果會立刻顯示:§2.4Ruby-ri和Perl一樣,Ruby也設計了嵌入式文檔。 ruby-ri就是查看文檔的工具。Ruby-ri的執行命令為“ri”,例如你可以通過“ri String.new”來查詢String類的new方法:§2.5R

28、ubyGemsRubyGems是Ruby社區流行的包管理工具,在以前如果要下載一個Ruby擴展或者應用程序的話,你需要先下載相應的zip包,然后解壓縮,再將應用或者擴展安裝到Ruby對應的目錄中。但是有了RubyGems所有這些麻煩都沒有了,你只需要一條命令就可以從遠程服務器上下載相應的包,如果相應的應用包含其他擴展,RubyGems會提示你從遠程安裝所依賴的擴展。安裝后 RubyGems會運行相應的程序生成rdoc幫助文檔。當然你也可以將軟件包下載到本地運行RubyGems本地安裝命令。統一化的管理帶來的好處就是簡單,有了RubyGems包管理器,Ruby應用的安裝將變得前所未見的容易。Ru

29、byGems是Rubyforge下載量最大的項目之一,現在Ruby社區的應用都在朝著RubyGems的方向發展,RubyGems也將成為Ruby事實上的包管理器標準。RubyGems包管理器的可執行命令是“gem”,gem命令包含很多子命令和相應的選項,例如:gem -h/-help 顯示命令幫助gem -v/-version 顯示Gems的版本號第三章 類與對象Ruby是一種真正的面向對象程序設計語言,面向對象指以對象為中心的理論體系。l 封裝(Encapsulation)將內部結構和算法隱藏起來,以確保只有特定的過程(也叫方法)才能直接操作數據,其結果是不能從外部直接使用數據構造,同時一旦

30、內部構造發生變化也不會對外界造成不良影響。這種隔離方法就叫做封裝。l 繼承l 多態(Polymorphism)根據對象的不同選擇合適的操作。在Ruby中的實現方法是,根據被調的對象的不同來選擇不同的方法。雖然有很多語言都宣稱自己是面向對象的,但是他們往往對面向對象的解釋都一樣,大多是以自己特有的方式來解釋什么是面向對象,而在實際情況中,這些面向對象語言又采用了很多非面向對象的做法。以 Java 為例:如果你想取一個數字取絕對值,java 的做法是:int num = Math.abs(-99);也就是將一個數值傳遞給 Math 類的一個靜態函數 abs 處理。為什么這么做?因為在 java 中

31、,數值是基本類型不是類。而在 Ruby 中,任何事物都是對象,也就是說,數字99就是對象,取絕對值這樣的操作應該屬于數字本身,所以Ruby的做法就是:c = -99.abs在Ruby中,你所操作的一切都是對象,操作的結果也是對象。§3.1 類的定義類是對具有同樣屬性和同樣行為的對象的抽象,Ruby中類的聲明使用class關鍵字。定義類的語法如下,class ClassNamedef method_name(variables)#some codeendend類的定義要在classend之間,在上面的格式中,ClassName是類名,類名必須以大寫字母開始,也就是說類名要是個常量。看下

32、面的例子:class Persondef initialize(name, gender, age)name = namegender = genderage = ageendend若某個類已經被定義過,此時又用相同的類名進行類定義的話,就意味著對原有的類的定義進行追加。class Testdef meth1puts "This is meth1"endendclass Testdef meth2puts "This is meth2"endend在Test類中,原有meth1方法,我們又追加了meth2方法,這時候,對于Test類的對象,meth1和m

33、eth2同樣可用。§3.2 對象,屬性和方法類在實例化后生成對象,在強調對象歸屬于某類時,有時候我們也使用實例對象一詞。方法(Method)是對對象進行的操作。操作對象(被調)以self來表示。在Ruby中,除去內部類的對象以外,通常對象的構造都是動態確定的。某對象的性質由其內部定義的方法所決定。看下面的例子,我們使用new方法構造一個新的對象,class Persondef initialize(name, gender, age)name = namegender = genderage = ageendendpeople = Person.new('Tom',

34、'male', 15)我們可以使用Person.new方法來創建一個Person類的實例對象。以打頭的變量是實例變量,他們從屬于某一實例對象,Ruby中實例變量的命名規則是變量名以開始,您只能在方法內部使用它。initialize方法使對象變為“就緒”狀態,initialize方法是一個特殊的方法,這個方法在構造實例對象時會被自動調用。對實例進行初始化操作時,需要重定義initialize方法。類方法new的默認的行為就是對新生成的實例執行initialize方法,傳給new方法的參數會被原封不動地傳給initialize方法。另外,若帶塊調用時,該塊會被傳給initializ

35、e方法。因此,不必對new方法進行重定義。在Ruby中,只有方法可以操作實例變量,因此可以說Ruby中的封裝是強制性的。在對象外部不可以直接訪問,只能通過接口方法訪問。class Persondef namenameenddef gendergenderenddef ageageendendpeople = Person.new('Tom', 'male', 15)puts puts people.genderputs people.age輸出結果為:Tommale15在Ruby中,一個對象的內部屬性都是私有的。上面的代碼中,我們定義了方法

36、name,gender,age三個方法用來訪問Person類實例對象的實例變量。注意name,gender,age訪問只能讀取相應實例變量,而不能改變它們的值。我們也可以用成員變量只讀控制符attr_reader來達到同樣的效果。class Personattr_reader :name, :gender, :ageend類似地,我們可以定義方法去改變成員變量的值。class Persondef name=(name)name=nameenddef gender=(gender)gender=genderenddef age=(age)age=ageendendpeople = Person.

37、new('Tom', 'male', 15)= "Henry"people.gender= "male"people.age= 25也可以用成員變量寫控制符attr_writer來達到同樣的效果。class Personattr_writer :name, :gender, :ageend我們也可以使用attr_accessor來說明成員變量既可以讀,也可以寫。class Personattr_accessor :name, :gender, :ageend也可以使用attr控制符來控制變量是否可讀寫

38、。attr 只能帶一個符號參數, 第二個參數是一個 bool 參數,用于指示是否為符號參數產生寫方法。它的默認值是 false,只產生讀方法,不產生寫方法。class Personattr :name, true#讀寫attr :gender, true#讀寫attr :age, true#讀寫attr :id, false#只讀end注意attr_reader,attr_writer,attr_accessor和attr不是語言的關鍵字,而是Module模塊的方法。class Testattr_accessor :valueendputs Test.instance_methods - Te

39、st.superclass.public_methods執行結果為:valuevalue=上面代碼中,我們使用Test.instance_methods得到Test類所有的實例方法,使用Test.superclass.public_methods得到Test父類所有的實例方法,然后相減就得到Test類不包含父類的所有的實例方法。由于instance_methods方法返回值為一個Array,所以我們作差值運算,Array的具體操作后面章節會講到。也可以重定義方法,重定義一個方法時,新的定義會覆蓋原有的定義。下面的例子重定義類中的方法meth1,class Testdef meth1puts &

40、quot;This is meth1"endenda = Test.newa.meth1class Testdef meth1puts "This is new meth1"endenda. meth1執行結果為:This is meth1This is new meth1重定義同一個類時,意味著對原有定義進行補充,不會覆蓋原來的定義。而重定義方法時,則會覆蓋原有定義。我們可以使用self標識本身,self和Java中的this有些類似,代表當前對象。class Persondef initialize(name, gender, age)name = nameg

41、ender = genderage = ageenddef <=>(other)self.age <=> other.ageendend<=> 方法通常意思為比較,返回值為-1,0或1分別表示小于,等于和大于。§3.3 繼承Ruby繼承的語法很簡單,使用 < 即可。class Student < Persondef initialize(name, gender, age, school)name = namegender = genderage = ageschool = schoolendendRuby語言只支持單繼承,每一個類都只

42、能有一個直接父類。這樣避免了多繼承的復雜度。但同時,Ruby提供了mixin的機制可以用來實現多繼承。可以使用super關鍵字調用對象父類的方法,當super省略參數時,將使用當前方法的參數來進行調用。class Basedef meth(info)puts "This is Base #info"endendclass Derived < Basedef meth(info)puts "This is derived #info"superendendobj1 = Derived.newobj1.meth("test")執行結

43、果為:This is derived testThis is Base test如果傳入的參數被修改再調用super的話,那么將會使用使用修改后的值。class Basedef meth(info)puts "This is Base #info"endendclass Derived < Basedef meth(info)puts "This is derived #info"info = "over"superendendobj1 = Derived.newobj1.meth("test")執行結果為:

44、This is derived testThis is Base over§3.4 特殊方法與特殊類特殊方法是指某實例所特有的方法。一個對象有哪些行為由對向所屬的類決定,但是有時候,一些特殊的對象有何其他對象不一樣的行為,在多數程序設計語言中,例如C+和Java,我們必須定義一個新類,但在Ruby中,我們可以定義只從屬于某個特定對象的方法,這種方法我們成為特殊方法(Singleton Method)。class SingletonTestdef infoputs "This is This is SingletonTest method"endendobj1 =

45、SingletonTest.newobj2 = SingletonTest.newdef puts "This is obj2"執行結果為:This is This is SingletonTest methodThis is obj2有時候,我們需要給一個對象定義一系列的特殊方法,如果按照前面的方法,那么只能一個一個定義: def obj2.singleton_method1enddef obj2.singleton_method2enddef obj2.singleton_method3enddef obj2.

46、singleton_methodnend這樣做非常繁復麻煩,而且無法給出一個統一的概念模型,因此Ruby提供了另外一種方法, class << objendobj是一個具體的對象實例,class << 代表它的特殊類。class SingletonTestdef meth1puts "This is meth1"enddef meth2puts "This is meth2"endendobj1 = SingletonTest.newobj2 = SingletonTest.newclass << obj2def me

47、th1puts "This is obj2's meth1"enddef meth2puts "This is obj2's meth2"endendobj1.meth1obj1.meth2obj2.meth1obj2.meth2執行結果為:This is meth1This is meth2This is obj2's meth1This is obj2's meth2§3.5 類變量與類方法類變量被一個類的所有實例對象共享,也可以被類方法訪問到。類變量名以,開始,例如number。和全局變量,實例變量不同,類

48、變量在使用前必須初始化:class Personnumber = 0 #使用前必須有初值def initialize(name, gender, age)name = namegender = genderage = agenumber += 1endend類變量是私有的,在類外無法直接訪問,你只能通過實例方法和類方法去訪問它。同樣,類方法是屬于一個類的方法,定義類方法時需要在方法前加上類名:class Personnumber = 0 def initialize(name, gender, age)name = namegender = genderage = agenumber += 1

49、enddef Person.getNumber #類方法return numberendend除了Person.getNumber這種方式定義類方法外,還可以使用其它方式定義類方法,在后續章節可以陸續見到。§3.4 存取控制當你設計一個類時,你需要決定哪些屬性和方法可以在類外被訪問到,哪些屬性和方法在類外被隱藏。如果一個類有過多的屬性和方法在類外可以被訪問到,那么勢必破壞這個類的封裝性。幸運的是在Ruby中,只能通過方法去改變一個類的屬性,這樣我們只需要考慮方法的存取控制。方法的存取控制有三種:l 公有方法(Public Method)n 方法在任何地方都可以被調用,這是方法的默認存

50、取控制。除了initialize和initialize_cpoy方法,他們永遠是私有方法。l 保護方法(Protected Method)n 方法只能被定義這個方法的類自己的對象和這個類的子類的對象所訪問。l 私有方法(private Method)n 方法只能被定義這個方法的類的對象自己訪問,即使是這個類的其他對象也不能訪問。Ruby中的保護方法和私有方法與一般面向對象程序設計語言的概念有所區別,保護方法的意思是方法只能方法只能被定義這個方法的類自己的對象和子類的對象訪問,私有方法只能被對象自己訪問。class Testdef method1 #默認為公有方法endprotected#保護方

51、法def method2endprivate#私有方法def method3endpublicdef test_protected(arg) #arg是Test類的對象arg.method2 #正確,可以訪問同類其他對象的保護方法enddef test_private(arg)#arg是Test類的對象arg.method3 #錯誤,不能訪問同類其他對象的私有方法endendobj1 = Test.newobj2 = Test.newobj1.test_protected(obj2)obj1.test_private(obj2)可以看到,和C+/Java相比,Ruby提供了更好的封裝性。也可以

52、使用以下更簡單的形式:class Testdef method1.enddef method2.enddef method3.enddef methdo4.endpublic:method1protected:method2private:method3, :method4endRuby和C+/Java的一個顯著不同是存取控制是程序運行時決定的而不是靜態綁定的。所以只有在訪問一個受限制的方法時才會產生運行時錯誤。§3.6 元類在Ruby中一切都是對象。類和實例對象都是對象。這句話聽起來有點拗口,讓我們來看一個例子:class Persondef initialize(name, ge

53、nder, age)name = namegender = genderage = ageendenda = Person.new('Tom', 'male', 15)puts a.object_id=>22429840puts Person.object_id=>22429960沒錯,類也是對象,這是Ruby和C+/Java的一個顯著不同,在C+/Java中,類僅僅是一個數據抽象,并沒有類也是對象這樣的概念。而在Ruby中存在著元類的概念,類也是對象,所有類都是元類的實例對象。和C+/Java相比,Ruby的面向對象程度更高。可以看到,類對象和實例

54、對象一樣有自己的ojbect_id,你可以象調用一個實例對象的方法一樣去用它去調用類方法。所有類對象的類是Class類,Oject類是所有類的基類。irb(main):003:0> Object.class=> Classirb(main):004:0> Object.superclass=> nil這樣,我們可以從另一個角度去理解類變量與類方法,類變量就是一個類對象的實例變量,類方法就是指一個類對象類的特殊方法。類方法具體可分為兩種:第一種是在所有的類的父類Class中定義的,且被所有的類所共享的方法;第二種是各個類所特有的特殊方法。類方法中的self指的是類本身,這

55、點需要牢記,這樣我們可以使用多種方式定義類方法。class Test#定義類方法方式1def Test.meth1# .end#定義類方法方式2def self.meth2# .end#定義類方法方式3class << Testdef meth3# .endend#定義類方法方式4class << selfdef meth4# .endendend§3.7 Ruby的動態性可以重新定義同一個方法,class RedefTestdef methputs "This is meth"endendobj1 = RedefTest.newobj1.

56、methclass RedefTestdef methputs "This is new meth"endendobj1.meth執行結果為:This is methThis is new meth可以使用undef_method取消一個方法的定義,class UndefTestdef methputs "This is meth"endendobj1 = UndefTest.newobj1.methclass UndefTestundef_method(:meth)endobj1.meth執行結果為:This is methtest.rb:14: un

57、defined method meth' for #<UndefTest:0x2ac8240> (NoMethodError)§3.8 變量變量名長度只受內存大小的限制。可以通過區分Ruby變量名的首字符來區分它是局部變量、實例變量、類變量、全局變量還是常量。通常情況下,變量名的第二位字符以后是數字、字母或下劃線,但有的內部變量名比較特殊,如“$?”。§3.8.1局部變量局部變量以小寫字母或下劃線開始。num = 1foo局部變量的作用域起始于聲明處,結束于該聲明所在的塊、方法定義、類模塊定義的結尾。2.times p defined?(num) num = 10 p num輸出為:nil10nil10即使聲明部分未被解釋器執行仍有效,因為已經經過解釋器的處理。v = 1 if falsep defined?(v)p v輸出為:"local-variable"nil但若塊已經變成過程對象的話,則局部變量將一直持續到該過程對象終結為止。若多個過程對象引用同一個作用域的話,局部變量將被這些對象所共享。(t

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論