2010-06-18 2 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 singleton class

Почему я не могу пойти:

X = MyClass.new 
X.my_method 
+0

Я взял на себя смелость редактировать вопрос, чтобы использовать термин «singleton class», поскольку это официальное название. В самом деле, Ruby 1.9.2 вводит «Object # singleton_class» –

ответ

6

include ModuleName добавляет методы из модуля, как например методы в том числе класса.

Так что, если вы пишете

class MyClass 
    include MyModule 
end 

затем my_method становится методом экземпляра на MyClass например,

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

При включении модуля внутри одноплодном класса методы продолжают добавляться как методы экземпляра, но к экземпляру класса Class для вашего класса. Поэтому они отображаются как методы класса на MyClass.

EDIT (Jörg W 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

. Ваш вопрос уже охватывает все базы, поэтому я добавил свои замечания как редактирование вместо отдельного ответа. –

+0

@ Jörg Спасибо за это - я всегда использовал 'extend' сам, так что не думал о' включении' в singleton-классе до вопроса Dex. – mikej

+0

Я взял на себя смелость редактировать ответ, чтобы использовать термин «singleton class», поскольку это официальное название. Действительно, Ruby 1.9.2 вводит «Object # singleton_class» –