Наследование методов класса от модулей/примесей в Ruby

Известно, что в Ruby методы класса наследуются:

class P
  def self.mm; puts 'abc' end
end
class Q < P; end
Q.mm # works

Однако меня удивило, что это не работает с миксинами:

module M
  def self.mm; puts 'mixin' end
end
class N; include M end
M.mm # works
N.mm # does not work!

Я знаю, что метод #extend может сделать это:

module X; def mm; puts 'extender' end end
Y = Class.new.extend X
X.mm # works

] Но я пишу миксин (или, скорее, хотел бы написать), содержащий как методы экземпляра, так и методы класса:

module Common
  def self.class_method; puts "class method here" end
  def instance_method; puts "instance method here" end
end

Теперь я хотел бы сделать следующее:

class A; include Common
  # custom part for A
end
class B; include Common
  # custom part for B
end

Я хочу, чтобы A, B наследовали и экземпляр, и методы класса из модуля Common. Но, конечно, это не работает. Итак, не существует ли секретного способа заставить это наследование работать из одного модуля?

Мне кажется неэлегантным разделять это на два разных модуля, один для включения, другой для расширения. Другим возможным решением было бы использование класса Commonвместо модуля. Но это всего лишь обходной путь. (Что, если есть два набора общих функций Common1и Common2и нам действительно нужны примеси?) Есть ли какая-то глубокая причина, по которой наследование методов класса не работает от примесей?

89
задан Máté Solymosi 16 July 2017 в 10:14
поделиться