Rock Say Ruby

遊手好閒的石頭成整理的 Ruby 語言文件。
個人部落格: 石頭閒語

2007年6月11日 星期一

 

Ruby User's Guide::Inheritance

繼承

English version: Inheritance

我們日常的個體分類系統是自然地階級分層。我們認知所有的貓都是哺乳動物,所有的哺乳動物都是動物。較小的類別繼承了具有分類歸屬關係之較大類別的特性。如果哺乳動物會呼吸,則貓就會呼吸。此一概念在 Ruby 中的表達方式如下例:

雖然我們未曾具體描述貓應該如何呼吸,但由於貓被定義為哺乳動物的子類別,故每一隻貓仍將繼承哺乳動物類的行為特徵。在個體導向的術語中,較小的類別稱為子類別(subclass)或衍生類別(derived class),較大的類別稱為父類別(superclass)或基礎類別(base class)。因此從程序員的觀點看,貓自然會擁有呼吸的能力。在我們添加發聲方法之後,我們的貓就能呼吸與發聲。

譯注: tama 即「玉(たま)」的日文發音,日本人常常替小貓取這個名字。

有時候,特殊的子類別不能繼承父類別的某些行為特徵。舉例而言,一般的鳥類都會飛翔,但企鵝卻是一種不會飛的鳥類。在個體導向的術語中,我們稱這種情形是行為的特化或偏化。(譯注: 參考《PHP 的參照及唯讀參照之實作》。雖然是 PHP 的文章,但其中的實踐內容非常適合說明繼承原則的特化與返祖化問題。)

我們不需要鉅細靡遺地定義每一個新類別的每一個行為特徵,僅需要增加或重定義子類別與父類別不同之處即可。這是繼承原則為個體導向編程所帶來的好處之一。

標籤:


2007年4月17日 星期二

 

Ruby User's Guide::Classes

類別

English version: Classes

真實世界是由一個個獨立個體所構成,我們將這些獨立個體按其屬性、行為抽象化地分門別類,於是有了各種類(classes)。例如,當一名很小的小孩子看到一隻狗時,可能會說 "汪汪" ,而不關心它的品種。我們很自然地以分類方式看待天地萬物。

在個體導向編程技術中,個體的種類,如「狗」,稱之為「類(class)」。歸屬於某一類的個體則稱為該類的實例(instance)。

在 Ruby 或任何個體導向語言中,要建置一個體時,首先要定義類的特徵,然後建立一個實例。下例闡明此過程,首先定義一個簡單的 Dog 類。

在 Ruby 的關鍵字 classend 之中的程式碼,即為類的定義內容。在此範圍中的 def 定義了類別的方法 — 如前章如述,即對應於此類個體的具體行為。

我們已經定義了 Dog 類,接著可以建立一個 dog (在 Ruby 的語言慣例中,首字母大寫者表示「類」,小寫表示類別的實例):

我們做了一個 Dog 類的新實例,並命令為 pochi 。每個類別的方法 new 可建立該類別的一個實例。因為 pochi 是 Dog ,根據我們的類別定義,它將具有我們賦予 Dog 類的一切特性。由於我們的想法非常簡單,在此我們僅能要求 pochi 玩一種把戲。

建立某類的一個實例又稱為類別實例化、具現化。我們需要有生命、有實體的狗,才能交談;我們不能要求狗類此一概念可以咆叫。

另一方面,如果我們想要聽見一隻狗的叫聲而不在乎那條狗的存在,我們可以創造一隻暫時性的狗,讓它發出聲音後就消失。

你可能會說: "等等,這可憐的傢伙在咆叫之後就會消失?" 是的,如果我們懶得給它名字, Ruby 的自動垃圾收集功能將判定這是一隻不再需要的流浪狗,並無情地處理掉。這是好事,如此我們才能無後顧之憂地建立我們需要的每一隻狗。

標籤:


2007年3月21日 星期三

 

Ruby User's Guide::Methods

方法

English version: Methods

什麼是方法(method)? 在個體導向編程中,我們不希望外部直接操作個體內的資料;因為個體本身更了解這些資料應如何操作,故透過它提供的方式操作資料較為合適。這麼想吧,我們傳一些訊息給個體,這些訊息將引起個體做出某些動作或有意義的回應。我們只需知道傳什麼訊息可以讓個體做哪些工作,而不需關心個體內部的實際工作內容。那些允許我們要求個體完成或處理訊息的工作,就稱之為個體的方法或行為。「方法」或「行為」這兩種詞彙皆有使用。

在 Ruby 中,我們以句號 (.) 調用個體的方法。個體為主詞置於句號左側,方法為動詞置於句號右側。 Ruby 是在程式運行途中,依變數當前所指涉之個體決定如何調用方法回應訊息。

直覺可知這是在問此字串個體之長度為何。技術上,我們調用 "abcdef" 之個體方法 length

其他個體對「長度」的詮譯可能有些許差異,或者完全不同。

長度的意義根據我們所談及的對象不同而有所差異。我們第一次問 foo 之長度時,它指涉一個字串,故長度的意義為此字串的字元數。第二次問長度時,foo指涉一個陣列,在大多數情形下,此時長度的意義是指陣列的內容數量,故答案為 2 。

根據實際指涉之個體以及傳遞之訊息決定工作方法的方式,接近我們使用自然語言時的表達習慣:同一詞語會依對象不同而具有不同的意義。此為個體導向編程的特徵,我們將之稱為「多型(polymorphism)」。

當個體接收到一個它無法理解的訊息時,將喚起(raised)錯誤:

故我們需要知道個體接受哪些方法,雖然我們不須知道這些方法如何工作。

若方法需要引數(arguments)時,引數通常用小括弧包起,但可以也省略。

Ruby 有一個特殊變數稱為 self,它指涉發生行為之個體。因為 我們經常使用 "self.",所以在個體本身內部使用時,我們可以省略它。

傳統上的函數呼叫(function call)在 Ruby 中亦被視為方法調用。那些函數性的方法仍然具有類似傳統程式語言的函數之行為特徵。在 Ruby 中談到「函數」時,通常表示那些並非真正的個體方法,而是純粹的演算法或抽象的敘述。

標籤:


2007年3月11日 星期日

 

Ruby Programming Wikibook::Symbol

符號(Symbol)

將冒號(:)加在識別字前,即為符號。符號是一種識別用的記號,經常於雜湊表中作為鍵值。可用%s指定冒號之替用符號。

範例:

:abc    # just mark here as 'abc'
t1 = {:name => 'john', :age => 20}
puts t1[:name]
t2 = {%s'name' => 'smith', %s[age] => 16}
puts t2[:name]

一般而言,以符號作為雜湊表之鍵值時效能較佳。因為以字串為鍵值時,Ruby 必須計算字串的雜湊值;以符號為鍵值時則不需計算。熟悉 C/C++ 語言的程式員可以 enum 與 map 之差異比對:以符號為鍵值類似以 enum 建立表;以字串為鍵值類似以 map class 建立表。兩者效能差異顯著。

標籤:


 

Ruby Programming Wikibook::Variables and Constants

在 Ruby 中,我們可以識別字為一個變數命名,名稱沒有長度限制。一個尚未初始之變數,其值為nil

區域變數(Local Variable)

範例:

foobar

一個變數之名稱若以小寫英文字母 (a-z) 或底線字元 (_) 為首,則該變數即為域變數或方法之參數。區域變數只能在它初始化之區塊內存取。例如:

i0 = 1
loop {
i1 = 2
print defined?(i0), "\n"      # true; 已定義,"i0" 於上層區塊中初始化。
print defined?(i1), "\n"      # true; 已定義,"i1" 於此區塊中初始化。
break
}
print defined?(i0), "\n"        # true; 已定義,"i0 於此區塊中初始化。
print defined?(i1), "\n"        # false; 未定義,"i1" 於 loop 區塊中初始化。

實例變數(Instance Variable)

範例:

@foobar

一個變數之名稱若以 '@' 為首,即為實例本身的實例變數。實例變數屬於實例之一部份,其意義等於 C++/Java 語言中之私有資料成員(private data member)。事實上,Ruby 嚴格遵守一個變數只能在其初始化區塊中存取之定義,因此區塊以外之敘述不允許存取實例內之變數。若外部想存取實例變數,只能透過實例的方法

類別變數(Class Variable)

範例:

@@foobar

在 Ruby 中也是一個實在的個體,因此類本身也有內部的變數。其意義等於C++/Java語言中之類別私有靜態成員(private static class member)。

全域變數(Global Variable)

一個變數之名稱若以 '$' 為首,即屬全域變數;當程式運作時,可在任何地方存取它。 範例:

$foobar

常數(Constant)

範例:

FOOBAR

一個變數之名稱若以大寫英文字母 (A-Z) 為首,即為常數。Ruby 允許在初始化常數後又再次指派其他值,但會發出警告訊息。Ruby 的每個都是一個常數。

若試圖取得一個未初始常數之值,將會喚起一個NameError異常。

虛設變數(Pseudo Variable)

虛設變數具有變數的性質,但其意義固定,由 Ruby 按其意義決定虛設變數指涉的內容。若改變虛設變數之意義,將令 Ruby 發出異常。

self

指涉行為個體本身。和 C/C++ 語言之 this 關鍵字意義相同。

nil

表示「無此物」,這是 NilClass 類別的唯一實例。

true

「真」或「真值」,為 TrueClass 類別之唯一實例。

false

「偽」或「偽值」,為 FalseClass 類別的唯一實例。 (在 Ruby 中,nil 也視同 false,除此以外任何值都視同 true。)

標籤:


封存

2007-02   2007-03   2007-04   2007-06  

This page is powered by Blogger. Isn't yours?

訂閱 文章 [Atom]