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

class MyClass 
    class << self 
    include MyModule 
    end 
end 

MyClass.my_method # => "hello 

Je ne suis pas sûr pourquoi "include MyModule" doit être dans la classe singleton afin d'être appelé en utilisant juste MyClass.Question générale à propos de la classe Ruby singleton

Pourquoi ne puis-je aller:

X = MyClass.new 
X.my_method 
+0

J'ai pris la liberté d'éditer la question pour utiliser le terme 'singleton class' car c'est le nom officiel. En effet, Ruby 1.9.2 introduit 'Object # singleton_class' –

Répondre

6

include ModuleName ajoute les méthodes du module, comme par exemple méthodes de la classe, y compris.

Donc, si vous écrivez

class MyClass 
    include MyModule 
end 

alors my_method devient une méthode d'instance sur MyClass par exemple

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

Lorsque vous ajoutez le module dans la classe singleton les méthodes sont encore ajoutées en tant que méthodes d'instance, mais à l'instance de la classe Class pour votre classe. Par conséquent, ils apparaissent en tant que méthodes de classe sur MyClass.

EDIT (Jörg W Mittag): Cependant, vous ne devriez jamais faire cela, puisque including dans la classe singleton est le même que extending l'objet original, qui est préféré. Donc, ceci:

class MyClass 
    class << self 
    include MyModule 
    end 
end 

est la même que celle-ci:

class MyClass 
    extend MyModule 
end 

Vous devriez toujours utiliser cette dernière forme.

Plus généralement, ceci:

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

est la même que celle-ci:

foo = Object.new 
foo.extend MyModule 

EDIT (MAL): Si vous voulez vous faire méthode à la fois comme une méthode d'instance et une méthode, vous pouvez simplement définir votre méthode comme ci-dessus, et soit extend self ce qui rendra toutes les méthodes d'instance accessibles à l'objet module lui-même, ou bien utiliser module_function :my_method.

+0

Votre question couvre déjà toutes les bases, j'ai donc ajouté mes remarques sous forme d'édition au lieu d'une réponse séparée. –

+0

@ Jörg Merci d'avoir fait cela - j'ai toujours utilisé 'extend' moi aussi donc je n'avais pas vraiment pensé à' compris 'dans la classe singleton jusqu'à la question de Dex. – mikej

+0

J'ai pris la liberté d'éditer la réponse pour utiliser le terme 'singleton class' car c'est le nom officiel. En effet, Ruby 1.9.2 introduit 'Object # singleton_class' –