Статические методы в рубиновых модулях?
Можно ли объявлять статические методы в модуле в ruby?
module Software
def self.exit
puts "exited"
end
end
class Windows
include Software
def self.start
puts "started"
self.exit
end
end
Windows.start
В приведенном выше примере не будет выводиться сообщение "exited".
Возможно ли иметь только один экземпляр в модуле?
Ответы
Ответ 1
Определите свой модуль следующим образом (т.е. make exit
метод экземпляра в модуле):
module Software
def exit
puts "exited"
end
end
а затем используйте extend
, а не include
class Windows
extend Software
# your self.start method as in the question
end
При использовании:
irb(main):016:0> Windows.start
started
exited
=> nil
Объяснение
obj.extend(module,...) добавляет obj методы экземпляра из каждого модуля, заданные как параметр
... поэтому при использовании в контексте определения класса (с самим классом в качестве получателя) методы становятся методами класса.
Ответ 2
Поместите методы класса во вложенный модуль, а затем переопределите "включенный" крючок. Этот крюк называется в любое время, когда ваш модуль включен. Внутри крючка добавьте методы класса для каждого из них:
module Foo
def self.included(o)
o.extend(ClassMethods)
end
module ClassMethods
def foo
'foo'
end
end
end
Теперь любой класс, включая Foo, получает метод класса с именем foo:
class MyClass
include Foo
end
p MyClass.foo # "foo"
Любые неклассовые методы могут быть определены в Foo как обычно.
Ответ 3
Необходимо изменить две вещи, чтобы иметь возможность называть Windows.exit
:
-
Software#exit
должен быть методом экземпляра
-
Windows
требуется extend
Software
, а не include
it.
Это связано с тем, что extend
другой модуль ставит эти методы экземпляра модуля как текущие методы класса модуля, тогда как include
ввод модуля ставит методы как новые методы экземпляра.
module Software
def exit
puts "exited"
end
end
class Windows
extend Software
def self.start
puts "started"
self.exit
end
end
Windows.start
Выход:
started
exited
Ответ 4
В модуль можно включить статические методы:
module Software
def self.exit
puts "exited"
end
end
Software.exit
Выполнение этих отпечатков "вышло", как ожидалось.