Metaprogramming of Ruby 讀書筆記第一章
一、Ruby中關於類和對象的概念
1、對象:對象是一組實例變量外加一個指向其類的引用。對象的方法並不存在於對象本身,而是存在於對象的類中。所以這些方法被我們稱作類的實例方法。
圖:對象與類的關係,以及實例方法的歸屬
2、類:類其實是Class類的一個對象,外加一組實例方法和一個對其超類的引用。Class類是Module類增加了new()方法的子類,所以一個類必然是一個模塊。
3、每個類都有屬於自己的方法,比如new(),這些是Class類的實例方法。跟其他的對象一樣,類也必須通過引用進行訪問。我們通常使用一個常量來引用它們:也就是類名。
4、所有類都是Object類的子類,Object類是BasicObject的子類,BasicObject纔是ruby對象體系中的根節點。
圖:對象,類,Class類,Module類和Object類的關係
圖:Class的類,Object的類,Module的超類
5、關於include:當使用include引入一個模塊時,Ruby創建一個封裝該模塊的匿名類,並悄悄滴把它插入到當前類的祖先鏈中。其位置就在當前類的正上方。這時,.superclass方法並不能找到這個類,只有.ancestors纔會發現它的存在。這裏最常見的例子就是Object類是包含了Kernel模塊的(包含了諸如printf等方法)
如果有多個include的話,每次都在這個類的正上方插入,其餘的類順次提高一位:
class Book
include Printable
include Document
ancestors # => [Book, Document, Printable, Object, Kernel, BasicObject]
end
二、Ruby中的self和與衆不同的private
self本身的概念並沒有特別之處:最後一個調用某方法的對象就是該方法的當前對象(receiver)。顯然,self本身就是一個正常的對象,只不過它的具體內容是不斷變化的。
問題在於Ruby中私有(private)的規則:
私有規則:私有方法只能被“隱含的” 接受者調用。
class C
def public_method
self.private_method
end
private
def private_method; end
end
C.new.public_method
NoMethodError: private method ‘private_method' called [...]
上面的這次實驗本不應該有問題的——除了它使用self來調用了自己定義的私有方法。去掉self之後,代碼正常。 原因:我們不能顯式地指定某個對象(包括使用self來指定)來調用私有方法。
有了這條鐵律,我們可以明確的得到一些事實:同一個類的不同實例能不能直接互相調用對方的私有方法?不能!無論如何你都得寫成x.method或者y.method,這是不行的。
我能不能調用父類中的私有方法?可以的,這個調用完全可以隱式地實現,不是麼。
(上面的事實可能令我們Java開發者有點掉下巴)
三、類和模塊的區別
書中介紹的其實足夠詳細了:類不過是個增強的Module,增加了new allocate superclass方法而已。有了這幾個方法你就可以創建對象並可以把它們歸納到類體系架構中(比如集成關係)。不過這裏似乎有更專業的解釋:Ruby的類與模塊
第一章,結束。