从父类重写类模块方法

时间:2013-10-10 16:16:34

标签: ruby object inheritance module

我有这个基本的例子

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的{​​{1}}会重新定义KlassModule klass_module_method TheirModule::Klass中最初定义的KlassModule ...

MyModule::Klass.do_something  # Hello from MyModule

这显然不是这样,我想知道......

  • 为什么这不起作用?
  • 完成此任务的红宝石方法是什么?

编辑:一个警告是我无法编辑TheirModule的来源

2 个答案:

答案 0 :(得分: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

虽然我说这看起来并不是一种非常红润的方式。也许可以重新组织类和模块以更清洁的方式实现这一点。

答案 1 :(得分:0)

非常简单的修复。试试self.do_something

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

这会强制该方法在当前类的上下文中查找KlassModule