Модули Ruby и расширения
В какой ситуации находится код:
module M
extend self
def greet
puts "hello"
end
end
более полезно использовать над чем-то вроде:
module M
def self.greet
puts "hello"
end
end
В верхней части, один - это метод экземпляра, который расширяется, а последний - только метод класса, но при вызове любого из методов вам нужно будет M.greet, правильно? Мне было просто любопытно, может ли кто-нибудь пролить свет на то, когда использовать один код над другим. Спасибо!
Ответы
Ответ 1
Первый пример обычно - это способ, которым люди достигают функциональности module_function
(когда они не знают о существовании этого метода).
A module_function
- это метод экземпляра и метод класса. В вашем втором примере кода метод - это просто метод класса.
Ответ 2
Это можно сделать с помощью первого примера, но не второго:
include M
greet
Ответ 3
Модуль можно использовать в качестве пространства имен, написав методы модуля, а методы экземпляра модуля могут быть смешаны с другим объектом.
Концепция саморасширяющегося модуля позволяет использовать модуль в обоих направлениях; либо как автономное пространство имен, либо как mixin. Рассмотрим этот модуль:
module M
def bar
puts "bar"
end
end
class C
include M
end
Он имеет метод экземпляра и может быть смешан с другим объектом. Он не имеет метода модуля и не может поэтому использоваться как пространство имен:
puts M::bar # => undefined method `bar' for M:Module
puts C.bar # => this is bar
Но модуль является просто объектом класса Module
, поскольку мы можем продемонстрировать
puts M.class # => Module
Это означает, что мы можем сделать что-то сумасшедшее. Мы можем объединить модуль в себя, чтобы его методы стали как экземплярами, так и модульными методами.
module M
extend self
def bar
puts "bar"
end
end
puts M::bar # => this is bar
puts C.bar # => this is bar