Рассмотрим следующее.
module B
def bi
"hello from bi"
end
def self.bm
"hello from bm"
end
end
B.instance_methods(false)
#=> [:bi]
B.methods(false)
#=> [:bm]
Обратите внимание, что определение метода модуля (здесь bm
) с помощью self.
такое же, как определение метода экземпляра для одноэлементного класса модуля.
Теперь создайте модуль A
, который включает B
.
module A
def self.am
"hello from am"
end
end
A.methods(false)
#=> [:am]
A.include B
A.instance_methods.include?(:bi)
#=> true
A.methods.include?(:bm)
#=> false
Как и ожидалось, bi
теперь является методом экземпляра A
. include
, однако, игнорирует методы модуля, здесь B::bm
. Есть ли способ для модульного метода B::m
стать модульным методом A
? Ответ - нет". По сути, мы хотим
A.singleton_class.include B.singleton_class
но это не работает, потому что B.singleton_class
- это класс.
Module # include не дает понять, может ли модуль (возможно, класс) включать класс. Попробуйте, однако, и вы увидите следующее исключение:
TypeError (wrong argument type Class (expected Module))
Если методы модуля модуля M
не доступны для другого модуля, который включает M
, есть ли причина для модулей иметь методы модуля? Да, предоставить библиотеки методов! Примером является модуль Math . Этот модуль содержит много методов модуля и никаких методов экземпляра. Поэтому при использовании эти методы вызываются на их приемнике Math
. Например,
Math.sin(x)