Хотя (возможно) не так чисто, как ответ Никласа, это все же легко выполнимо, и IMO чище, чем шаблон использования, показанный в ОП, который основан на знании, в какой модуль смешан.
(я предпочитаюне нужно передавать аргумент таким смешанным методам, когда существуют другие средства.)
Вывод:
pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto
Смелость:
module Mod
module ClassMethods
def hello
puts "saying hello..."
done
end
end
def self.included(clazz)
clazz.extend ClassMethods
end
end
Модифицированный классдекларации, удалив явную ссылку на модуль:
class A
include Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end
class B
include Mod
def self.ciao
hello
end
def self.done
puts "finitto"
end
end
Вы также можете предоставить реализацию по умолчанию done
:
module Mod
module ModMethods
def hello
puts "saying hello..."
done
end
def done
throw "Missing implementation of 'done'"
end
end
def self.included(clazz)
clazz.extend ModMethods
end
end
Как указано в комментарии к этому сообщению,если фрагмент в OP является точным представлением фактического варианта использования, вы можете также использовать extend
(вместо include
), оставляя все более чистым:
module Mod
def hello
puts "saying hello..."
done
end
def done
raise NotImplementError("Missing implementation of 'done'")
end
end
И классы, использующие extend
:
class A
extend Mod
def self.bonjour
hello
end
def self.done
puts "fini"
end
end