2010-06-18 82 views
1
module MyModule 
    def my_method; 'hello'; end 
end 

class MyClass 
    class << self 
    include MyModule 
    end 
end 

MyClass.my_method # => "hello 

我不確定爲什麼「包含MyModule」需要在單例類中才能使用MyClass來調用。關於Ruby單例類的一般問題

爲什麼我不能去:

X = MyClass.new 
X.my_method 
+0

我冒昧地編輯這個問題使用術語'singleton class',因爲它是正式名稱。事實上,Ruby 1.9.2引入了'Object#singleton_class' – 2010-06-18 15:16:02

回答

6

include ModuleName增加了從模塊方法爲例如方法到包括類。

所以,如果你寫

class MyClass 
    include MyModule 
end 

然後my_method成爲上MyClass例如實例方法

m = MyClass.new 
m.my_method # => "hello" 

當包括方法仍然被添加爲實例方法,但對類Class您的類的實例單身類中的模塊。因此它們在MyClass上顯示爲類方法。編輯(JörgW Mittag):但是,你永遠不應該那樣做,因爲在單例類中including與原始對象extending相同,這是首選。所以,這樣的:

class MyClass 
    class << self 
    include MyModule 
    end 
end 

是一樣的:

class MyClass 
    extend MyModule 
end 

你應該總是使用後一種形式。

更普遍的做法是:

foo = Object.new 
class << foo 
    include MyModule 
end 

是一樣的:

foo = Object.new 
foo.extend MyModule 

EDIT(MAL):如果你想有你的方法既作爲實例方法和方法,您可以簡單地定義上述方法,並且可以使用extend self這將使模塊對象本身可以訪問所有實例方法,也可以使用module_function :my_method

+0

你的問題已經涵蓋了所有的基礎,所以我添加了我的評論作爲編輯而不是單獨的答案。 – 2010-06-18 09:32:11

+0

@Jörg謝謝你這樣做 - 我一直都使用'extend',所以直到Dex的問題才真正考慮過單個類中的'included'。 – mikej 2010-06-18 09:46:07

+0

我冒昧地編輯了使用術語「singleton class」的答案,因爲它是正式名稱。事實上,Ruby 1.9.2引入了'Object#singleton_class' – 2010-06-18 15:15:13