2010-06-18 63 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