Time of Update: 2017-01-18
繼承允許你建立一個類,作為另一個類的精鍊(refinement)和特化(specialization)。例如,在我們的自動點唱機系統中,有“歌曲”這一概念,被封裝在Song類中,然後,隨著市場的成長,我們需要提供卡拉OK的支援。一首卡拉OK歌曲和其他歌曲沒什麼兩樣(它只是沒有主唱的音軌,對此我們不必關心)。不過,它還包括對於的一套歌詞以及時間資訊。當我們的自動點唱機在播放一首卡拉OK歌曲時,歌詞應該隨音樂滾動顯示在點唱機前的螢幕上。解決這個問題的一種方法是定義一個新的類KaraokeSong,就
Time of Update: 2017-01-18
模組與類很相似,它也可以說成是“不能被執行個體化的類”。由於Class類是Module類的子類,所以說成是“類=模組+執行個體化能力”也許更好。所謂模組,究竟是用來幹什麼的呢?其作用主要有兩大類:Mix-in和命名空間。Mix-in實際上是受限制的多重繼承。利用實際做成的繼承關係,可以實現對某些類進行一些“點綴”的目的。事實上,Mix-in這種說法就來自於在冰激淩上面的餅乾或者堅果。在物件導向設計的曆史中,由多重繼承機製造成的問題早已眾所周知了。所以,很多現代的物件導向設計語言都只支援單一繼承的
Time of Update: 2017-01-18
當調用一個方法時,Ruby會做兩件事。1.找到這個方法。這個方法稱為方法尋找。2.執行這個方法。為了做到這點,Ruby需要一個叫做self的東西。這樣的一個過程--發現一個方法再執行之--在每種物件導向語言中都會發生。不過,對於像Ruby這樣非常動態語言,深入理解這個過程顯得尤為重要。你有沒有好奇過一個方法究竟定義在哪裡呢?如果有,那絕對應該深入理解方法尋找及self。當調用一個方法時,Ruby會在對象的類中尋找那個方法。不過,在給出更複雜的例子之前,你需要瞭解兩個新概念:接收者(receive
Time of Update: 2017-01-18
一個運行著的程式常會遇到意外的問題.一個要讀取的檔案不存在;當希望存入一些資料時磁碟滿了;使用者可能輸入不恰當的資料. ruby> file = open("some_file") ERR: (eval):1:in `open': No such file or directory - some_file
Time of Update: 2017-01-18
一個常量由大寫字母開頭.它應最多被賦值一次.在Ruby的目前的版本中,常量的再賦值只會產生警告而不是錯誤(non-ANSI版的eval.rb不會報告這一警告) ruby>fluid=30 30 ruby>fluid=31 31 ruby>Solid=32 32 ruby>Solid=33 (eval):1:
Time of Update: 2017-01-18
局部變數由小寫字母或底線(_)開頭.局部變數不像全域和實變數一樣在初始化前含nil值. ruby> $foo nil ruby> @foo nil ruby> foo ERR: (eval):1: undefined local variable or method `foo' for&
Time of Update: 2017-01-18
一個實變數由@開頭,它的範圍限制在 self 對象內.兩個不同的對象,即使屬於同一個類,也可以擁有不同值的實變數.從對象外部來看,實變數不能改變甚至觀察(比如, Ruby的實變數從來不是公用的),除非方法由程式員明確聲明.像全域變數一樣,實變數在初始前的值是nil. Ruby的實變數用不著聲明.這暗含著對象的彈性結構.實際上,每個實變數都是在第一次出現時動態加入對象的. ruby> class InstTest
Time of Update: 2017-01-18
全域變數由$開頭.它們可以在程式的任何位置訪問到.在初始化前,全域變數有一個特殊的值 nil. ruby> $foo nil ruby> $foo = 5 5 ruby> $foo 5
Time of Update: 2017-01-18
Ruby有三類變數,一種常量和兩種嚴格意義上的偽變數(pseudo-variables).變數和常量都沒有類型.雖然無類型變數存在一定的缺點,但卻有更多的優點並很好的符合Ruby快速簡便(quick and easy)的哲學精神. 在大多數語言裡,變數都必須指定其類型,可更改性(是不是個常數)和範圍;由於類型的不存在,剩下的東西也可由變數名字很快確定(你馬上會看見),在Ruby裡我們不需要變數聲明. 由首字母標識符將其分類: $
Time of Update: 2017-01-18
我們總是希望對未知事件分類.當它發生時,向其它方法傳遞一塊作為參數的代碼是最容易地解決方案,也就是說我們希望像處理資料一樣處理代碼. 一個新的過程對象可以通過proc建立: ruby> quux = proc { | print "QUUXQUUXQUUX!!!\n" | } &
Time of Update: 2017-01-18
Ruby的模組非常類似類,除了: 模組不可以有實體 模組不可以有子類 模組由module...end定義. 實際上...模組的'模組類'是'類的類'這個類的父類.搞懂了嗎?不懂?讓我們繼續看下去吧. 模組有兩種用法.其一是將相近的方法和實體放在一個相對集中的域裡.Ruby標準包裡的Math模組就扮演著這一角色: ruby> Math.sqrt(2) 1.41421
Time of Update: 2017-01-18
實體的行為取決於其類,但很多時候我們知道一個特定的實體需要特定的行為.在很多語言裡,我們必須陷入另外再定義一個類的麻煩裡,即使它只是用來接著實體化一次.在Ruby裡,我們可以賦予任何對象屬於其自身的方法. ruby> class SingletonTest | def size
Time of Update: 2017-01-18
物件導向是一個挺讓人迷惑的措辭.叫一切東西都是物件導向會讓別人覺得你很時髦. Ruby 聲稱自己是物件導向的指令碼語言;但究竟什麼才是"物件導向"? 我們已經有了各種各樣的答案,但所有這些恐怕都歸結於同一件事.與其快速地概括它,不如讓我們先花點兒時間考慮一下傳統的編程模式.傳統意義上,一個編程問題從出現的各種資料,以及處理資料的過程(procedures)著手.在這一模式下,資料是呆板,被動和無用的;它完全的求助於那個體積龐大的,主動的,邏輯性的,全能的過程體.這一
Time of Update: 2017-01-18
迭代器並不是Ruby發明的.它廣泛地運用於各種物件導向語言.在Lisp中也有,只是不這麼叫罷了.儘管如此,迭代器的概念並不為許多人熟悉,因此我們將在此做較為詳細的介紹. 你知道,動詞 iterate 的意思是做同一件事許多遍,因此,iterator就是用來將同一件事做許多次的東西. 當我們寫代碼時,我們需要各種環境下的迴圈.在C裡,我們用for或者while.比如, char *str;
Time of Update: 2017-01-18
這章我們將討論更多的Ruby流程式控制制. case 我們用case語句測試有次序的條件.正如我們所見的,這和C,Java的switch相當接近,但更強大. ruby> i=8 ruby> case i | when 1, 2..5 | print "1..5\n"
Time of Update: 2017-01-18
現在我們將前面的一些樣本程式的代碼坼開來分析一下. 下面的例子出現在簡單的例子一節. def fact(n) if n == 0 1
Time of Update: 2017-01-18
你通過在方括弧裡列出元素並用逗號將它們相互隔開來建立一個數組. Ruby的數組可以適應不同的物件類型 ruby> ary = [1, 2, "3"] [1, 2, "3"] 就像前面提到的字串一樣.數組也可以相乘或相加 ruby> ary + ["foo", "bar"]
Time of Update: 2017-01-18
我們再看一個更有趣的程式.這次我們來測試一個字串是否和一個由簡明模式(concise pattern)編碼產生的描述相匹配. 在這些模式(pattern)裡,一些字元或字元組合都有獨特的意義,包括: 複製代碼 代碼如下:[] 範圍描述符 (比如,[a - z] 表示在a 到 z 範圍內的一個字母)
Time of Update: 2017-01-18
Ruby將字串像數字一樣處理.我們用單引號('...')或雙引號("...")將它們括起來.ruby> "abc" "abc"ruby> 'abc' "abc"單引號和雙引號在某些情況下有不同的作用.一個由雙引號括起來的字串允許字元由一個前置的斜杠引出,而且可以用#{}內嵌運算式.而單引號括起來的字串並不會對字串作任何
Time of Update: 2017-01-18
讓我們寫一個計算階乘的函數.對於階乘的數學定義如下: n! = 1 (當 n==0 時) = n * (n-1)! (其它情況)