2013-10-10 4 views
1

У меня есть этот рудиментарных примерметоды модуля Перекрытие класса из родительского класса

module TheirModule 
    class Klass 

    def self.do_something 
     KlassModule.klass_module_method() 
    end 

    module KlassModule 

     # Lots of other functionality 

     def self.klass_module_method 
     puts "Hello from TheirModule" 
     end 

     # Lots of other functionality 

    end 
    end 
end 

module MyModule 
    class Klass < TheirModule::Klass 

    module KlassModule 
     extend TheirModule::Klass::KlassModule 

     def self.klass_module_method 
     puts "Hello from MyModule" 
     end 

    end 
    end 
end 

Тогда называя это дает мне неожиданные результаты.

MyModule::Klass.do_something # Hello from TheirModule 

Я ожидаю, что MyModule::Klass «s KlassModule будет переопределить klass_module_method первоначально определенный в TheirModule::Klass» s KlassModule как это ...

MyModule::Klass.do_something # Hello from MyModule 

это явно не тот случай, и мне интересно ...

  • Почему это не работает?
  • Что было бы рубиновым способом для этого?

EDIT: Одно предостережение в том, что я не могу изменить источник TheirModule

+0

Кому следует переопределять какие? Это много запутанных имен. –

+0

@SergioTulentsev 'MyModule :: Klass.klass_module_method' должен переопределить' Ихмодуль :: Klass.klass_module_method' ... Или, по крайней мере, это то, что я намереваюсь сделать. – jondavidjohn

ответ

1

это будет работать без модификации оригинального кода TheirModule.

Есть два KlassModules

  • TheirModule::Klass::KlassModule
  • MyModule::Klass::KlassModule

В TheirModule::Klass имя KlassModule однозначно решает для TheirModule::Klass::KlassModule. Этот другой модуль, который вы определяете, полностью отделен от этого. Он не может переопределить что-либо.

Необходимо открыть и изменить первоначальный модуль, TheirModule::Klass::KlassModule. Например, это так.

module MyModule 
    class Klass < TheirModule::Klass 

    module ::TheirModule::Klass::KlassModule 
     def self.klass_module_method 
     puts "Hello from MyModule" 
     end 

    end 
    end 
end 

MyModule::Klass.do_something 
# >> Hello from MyModule 

Хотя я бы сказал, что это не выглядит очень рубиновым. Возможно, классы и модули могут быть реорганизованы для достижения этого более чистым способом.

+0

Не имея доступа к 'ИхModule' напрямую, это решило мою проблему. Спасибо. – jondavidjohn

+1

Небольшая проблема (не уверен, что это проблема для OP): это глобальное изменение поведения 'klass_module_method' для каждого отдельного подкласса ихModule :: Klass. – Linuxios

+0

@ Linuxios: да. Вместо этого он заменил синтаксис поиска на «self :: KlassModule». Однако это может также нарушить некоторый код клиента. –

0

Очень простое исправление. Попробуйте это для self.do_something:

def self.do_something 
    self::KlassModule.klass_module_method() 
end 

Это заставляет метод, чтобы искать KlassModule в контексте текущего класса.

+0

У меня нет доступа к 'ItsModule' Извините, в этом вопросе не было ясно. – jondavidjohn

+0

@ jondavidjohn: Понятно. Тогда кто бы ни разработал Их Модуль, если бы он предназначался для расширения, проектировал его очень плохо. Задержись на секундочку. – Linuxios

Смежные вопросы