JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Languages on JVM » JRuby  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
己加入精華區
by koji at 2007-07-26 22:20
本主題所含的標籤
無標籤
作者 Singleton Method And Singleton Class [精華]
weijenlu





發文: 30
積分: 6
於 2007-07-26 22:19 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
在現實的世界裡面,我們是可以為物件新增任何我們想要的功能的,例如說我為我的愛車加裝飛行的功能(前兩天的新聞,這是有可能的了),以後我只要按個按鈕,他就可以飛起來(但是我希望我沒在車子裡面)。那我們的程式是不是有可能這樣呢?我們可不可以在runtime為object新增一個或一組新的功能呢,在Ruby的世界裡這是可以辦到的。

Singleton Method
現在我就來說說怎麼為我的愛車新增飛行的功能。
首先我的車就跟一般的車是沒有什麼不同的,也就是說他是車子這個類別的一個實例(instance):
1
2
3
4
class Car
  end
  
  mycar=Car.new

接下來我要為我的車子增加飛行的功能:
1
2
3
def mycar.fly
    put “車子飛起來了。“
  end

就這麼簡單,當我要我的車子飛的時候我只需要:mycar.fly就可以了。
而這個fly method,就稱為singleton method。當我為mycar這個物件定義了這個singleton method,當然只有mycar這個物件能夠了解fly這個message,也才能夠正確的執行我希望的任務。
其實在我們撰寫ruby的時候,我們是很常用到singleton method的,因為對Ruby來說class method就是一種singleton method。

Singleton Class
其實在Ruby中,每一個物件其實是擁有兩個class的:
1.他所實做的那一個class(在上面的例子中就是Car class)。
2.他自己的singleton class。
而singleton method就是存在於這個物件的singleton class中。你可以把singleton class當作是一個專屬於某一個物件的存放區,存放只屬於這個物件的methods。而這個物件的能力,也就是這兩個class的能力的總和。從上述的例子中,一般車子的能力是定義在Car的類別中,而飛行的能力是定義在singleton class中,而我的車子就同時能在路上跑,又能飛了。

存取/修改singleton class
Singleton class是無名的,(ㄟ,有點敏感),是匿名的,那我們怎麼去存取或修改singleton class呢?我們可以利用下面的程式碼定義新的method或變數到物件中:
1
2
3
class << mycar
    #我的車子的新功能就定義在這裡
  end


使用class <<來定義class method
在ruby中,我們常見到下列的定義方式:
1
2
3
4
class Test
  class << self
    def c_method(parameter)
      #etc.

這個方式幫我們定義了一個Test class的class method=>Test.c_method。
如果Test class已經在別處定義好了,我們要新增class method,我們可以這樣:
1
2
3
class << Test
  def c_method(parameter)
    #etc.

在第一種方式中,因為我們在Test class的區塊內,self就是Test class,所以class << self就跟 class << Test是一樣的。
因為我們常看到class << self是用來定義class method的,所以誤以為class << 是專門用來定義class method的。事實上,class << self只是class << object的一個例子而已,class << object是讓我們可以定義object的singleton class的。而在其定義區塊中,你可以定義任何專屬於這個object的操作。

Method lookup path
而當物件在搜尋method時,singleton class中所定義的method是第一個被搜尋的,它的優先權是高於定義這個object的class的。因為singleton class是這個object存放專屬於自己的method的地方。
我們也可以mix-in module到singleton class中:
1
2
3
  class << mycar
    include NewFlyPackage
  end

這樣module NewFlyPackage中所定義的methods就成為mycar的singleton methods了。那Ruby也提供了extend method,讓我們直接min-in module:
1
  obj.extend(NewFlyPackage)

這兩個方法效果是一樣的。
那在method lookup path中,singleton class mix-in module的優先權介於singleton class,與此object所屬的class之間。
我用我的愛車的例子來說明:
1
2
3
4
5
6
7
8
9
10
11
  class Car
  end
 
  module NewFlyPackage
  end
 
  mycar=Car.new
  class << mycar
    include NewFlyPackage
    p ancestors
  end

其中ancestors會依照lookup path列出目前這個object所繼承的class或mix-in的module。而上面的例子會印出[NewFlyPackage, Car, Object, Kernel]可見mix-in到singleton class的module的優先權會高於此object所屬的class。

深入class method
class method其實是定義在class object的singleton method。Class method的定義方式其實就是singleton method的定義方式:
1
2
3
4
5
6
7
8
  class C
  end
 
  def C.a_class_method
    puts “Singleton method defined on C”
  end 
 
  C.a_class_method

但是class methods跟object的singleton methods還是有一點不一樣,object的singleton methods是專屬於這個object的,無法被其他object所使用,可是class method可以被定義他的class的subclass所使用,由上個例子延伸:
1
2
3
4
  class D < C
  end
 
  D.a_class_method

C的class method是會被D給繼承的。這是因為C的singleton class被視為是D 的singleton class的super class。

結論
說實在的,我也想不出來我的程式那時候會用到這個功能,我想Ruby for Rails介紹這個東西的實際目的應該是為了讓我們可以了解class method吧,不過取singleton這個名字,讓很多人都會想到Singleton Pattern,我昨天跟qing討論時也以為是同一個東西,可是看起來好像不是,不過無論如何,就像Ruby for Rails書上說的:Just about every in Ruby is dynamic。


reply to postreply to post
話題樹型展開
人氣 標題 作者 字數 發文時間
2810 [精華] Singleton Method And Singleton Class weijenlu 3311 2007-07-26 22:19
2843 Re:Singleton Method And Singleton Class koji 235 2007-07-26 22:50
» JWorld@TW »  Languages on JVM » JRuby

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8