Ruby 元程式設計 第二版隨筆(二)

2021-09-02 15:39:59 字數 2127 閱讀 4651

呼叫方法時發生了什麼? 

呼叫方法時ruby會做兩件事:

(1)找到這個方法,這個過程成為方法查詢。

(2)執行這個方法,為了做到這點,ruby要用到乙個稱為self 的東西。

1.方法查詢

method lookup

呼叫乙個方法前,ruby會在物件中查詢那個方法。不過,在進一步學習之前,我們還要掌握兩個新概念:接受者(receiver)和祖先鏈(ancestors chain)。接受者就是你呼叫方法所在的物件。例如,在my_string.reverse()語句中,my_string就是接收者。為了理解祖先鏈 的概念,可以先觀察乙個ruby類。想像從乙個類找到它的超類,然後依次往上找,直到找到basicobject(ruby類體系結構的根節點)。在這個過程中,經歷的類的路徑就是該類的祖先鏈。(祖先鏈中可能會包含模組,後面再說。)

知道了接收者和祖先鏈,就可以用一句話來概括方法查詢的過程:ruby首先在接收者的類中查詢。然後順著祖先鏈向上查詢,直到找到這個方法為止。

class myclass

def my_method; 'my_method'; end

endclass mysubclass < myclass

end

obj = mysubclass.new

obj.my_method() # => "my_method()"

我們已經知道了祖先鏈是從類開始到其超類結束。 實際上,祖先鏈中也包含模組(module)。當吧一      個模組包含在乙個類(或者乙個模組)中時,ruby就會把這個模組加入該類的祖先鏈中,該模組在祖先鏈      中的位置就在包含它的類之上。

module m1

def my_method

'm1#my_method()'

endendclass c

inculde m1

endclass d < c; en

d.ancestors            #  =>  [d, c, m1, object, kernel, basicobject]
從ruby 2.0 開始,還可以用另外一種方法吧模組插入乙個類的祖先鏈中:使用prepend方法。 他的功能和include方法相似, 不過這個方法會把模組插入到祖先鏈中包含它的該類的下方,而不像include方法那樣插入上方:

class c2

prepend m2

endclass d2 < c2; end

d2.ancestors                #   =>  [d2, m2, c2, object, kennel, basicobject]
關於include和prepend,還有乙個重要的知識點。

多重包含

如果試圖在某個類的祖先鏈中多次加入同乙個模組,會如何呢?

module m1; end

module m2

include m1

endmodule m3

prepend m1

inculde m2

end

m3.ancestors        #  => [m1, m2, m3]
可以看出雖然我們多次的新增模組但是最後並沒有重複,每次include或者prepend的時候,如果該模組 已經存在於祖先鏈中, 那麼ruby會悄悄的忽略這個包含(include或prepend)指令。因此乙個模組只會在一條祖先鏈中出現一次。

無處不在的kernel模組

ruby中有一些方法(如print)可以隨時隨地的進行呼叫,看起來就像是所有物件都有print方法一樣。這是因為這些方法實際上都是kerenl模組的私有方法:

kernel.pricate_instance_methods.grep(/^pr/) # => [:printf, :print, :proc]
這裡的秘密在於object類包含了kernel模組,因此kernel模組就進入了每個物件的祖先鏈。於是,無論哪個物件都可以隨意呼叫kernel模組的方法。這使得print看起來就像乙個關鍵字,其實它只是乙個方法而已。 

Ruby 元程式設計 第二版隨筆(三)

執行方法 method execution 呼叫方法時,ruby要做兩件事 首先找到這個方法,然後執行這個方法。到目前為止,我們只學會了如何找到這個方法,接下來看看如何執行方法。假設我們自己就是ruby直譯器,現在呼叫了乙個名叫my method的方法,我們先找到方法,發現該方法定義如下 def m...

GNU Linux程式設計指南 第二版

本書全面而深入地介紹了gnu linux程式設計。首先介紹了在linux上程式設計必備的程式設計工具,然後在庫函式 系統呼叫以及核心上闡述linux程式設計知識,並專門講述了包括tcp ip udp以及多播套介面在內的網路程式設計知識 圖形介面也是本書的重點內容,本書著重講述了文字形式的圖形介面庫n...

《演算法競賽入門經典(第二版)》 隨筆

c語言中整數值用 d輸出,實數 浮點數 用 f輸出。kiss原則 keep it and stupid 獲得程式執行時間 包括鍵盤輸入時間 include printf 執行時間 2f n double clock clocks per sec 輸入個數未知時 while scanf d x 1 對...