Из того, что я понимаю, вы хотите переопределить A#foo
(который также используется B#bar
) внутри MyClass
.Однако вы хотите переопределить его только внутри MyClass
, а не для кода в B
mixin.
Здесь нужно понимать, что когда код A
и B
mixin запускаются, они будут частью MyClass
экземпляра.Поэтому невозможно переопределить методы экземпляра MyClass
, не влияя на миксины.Это как если бы методы миксинов были брошены в ведро (экземпляр MyClass
), а затем запущены.У них нет отдельных областей применения.Поэтому простой ответ: нет, вы не можете этого сделать.
Хотя может быть несколько возможных решений, многие из которых пахнут пастой .Подобные проблемы могут указывать на то, что общие проектные решения требуют некоторого рефакторинга.
Рассмотрим основы модулей:
module Numbered
DEFAULT = "1234-AWESOME"
def serial_number
DEFAULT
end
def self.awesome?
true
end
end
Numbered.awesome? # => true
Numbered.serial_number # whoops! NoMethodError.
o = Object.new
o.extend(Numbered)
o.serial_number #=> "1234-AWESOME"
Numbered.extend(Numbered)
Numbered.serial_number # => "1234-AWESOME"
class Dog
extend Numbered
end
Dog.serial_number # => "1234-AWESOME"
Dog::DEFAULT # => "1234-AWESOME"
fido = Dog.new
fido.serial_number # NoMethodError!
Это потому, что метод был добавлен какметод класса.include
на помощь:
class Fish
include Numbered
def serial_number
super + '-FSH'
end
end
cod = Fish.new
cod.serial_number # => "1234-AWESOME-FSH"
Итак, include
объединяет все методы в один общий экземпляр, но мы все равно можем использовать super
для вызова включенного метода, который мы переопределяем.Если вы выберете решение для макаронных изделий, вы можете использовать super внутри метода bar
, условно вызывая метод, который вы переопределяете.
Также, в зависимости от случая, вы можете настроитьновый модуль и extend
с модулем, содержащим методы, к которым вам нужен доступ, как в ответе, который вы добавили.