从另一个模块覆盖类方法

时间:2016-11-23 17:01:41

标签: ruby module

我想从库中修改现有模块A

module A
  class << self
    def foo
      bar('Baz')
    end

    private

    def bar(val)
      val.upcase
    end
  end
end

A.foo
=> "BAZ"

module B
  extend A

  def self.bar(val)
    val.downcase
  end
end

B.foo            # hoping for 'baz', but instead:
NoMethodError: undefined method `foo' for B:Module

有没有办法从.foo重新使用方法A,只修改方法.bar

2 个答案:

答案 0 :(得分:4)

extend A无效,因为foobar不是A的实例方法,而是A的实例方法单身课程。要重新使用这些方法,您必须创建一个A的副本作为mudasobwa描述,或者您可以使用A的单例类的细化:

module B
  extend(refine(A.singleton_class) do
    def bar(val)
      val.downcase
    end
  end)
end

B.foo # => "baz"

您无法使用extend A.singleton_class,因为extend不接受某个类作为参数。 refine会返回一个完全符合要求的模块。

答案 1 :(得分:2)

假设您已按上述方式声明A,则可执行以下代码:

▶ B = A.clone
#⇒ B
▶ (class << B; self; end).send :define_method, :bar do |val|
  val.downcase
end
▶ A.foo
#⇒ "BAZ"
▶ B.foo
#⇒ "baz"

可能应该不那么棘手,但我还不知道。