Ruby模块类方法继承

Ruby模块类方法继承,ruby,module,Ruby,Module,如何使嵌套的一系列模块中定义的类方法向上传播模块混合树 考虑以下几点: module A def self.included(base) base.extend(ClassMethods) end def foo; end module ClassMethods def bar; end end end module B include A end class C include B end puts "B class methods:

如何使嵌套的一系列模块中定义的类方法向上传播模块混合树

考虑以下几点:

module A
  def self.included(base)
    base.extend(ClassMethods)
  end

  def foo; end

  module ClassMethods
    def bar; end
  end
end

module B
  include A
end

class C
  include B
end

puts "B class methods:   #{(B.methods-Module.methods).inspect}"
puts "B instance methods #{B.instance_methods.inspect}"
puts "C class methods:   #{(C.methods-Class.methods).inspect}"
puts "C instance methods #{(C.instance_methods-Class.instance_methods).inspect}"
类C不继承A中定义的类方法,即使它包含B

B class methods:   [:bar]
B instance methods [:foo]
C class methods:   []
C instance methods [:foo]
是否有一种简洁的方法可以确保类方法从a向上传播到C(这样我就可以调用C.bar)?我正在寻找一种很好的通用方法,它不涉及用每个继承的模块专门调用和扩展C

问候


Steve

如果您不想手动扩展
ClassMethods
,并且希望包括
B
在内的任何人通过
ClassMethods
扩展其类接口,您可以这样做:

module B
  include A

  def self.included(base)
    base.extend(ClassMethods)
  end
end

或者您可以将
B
定义为
class
,并从中继承
C
。我想这一切都取决于你的设计和你想要达到的目标。

好吧,所以我想出来了。这是一个轻微的攻击,因为它依赖于模块层次结构,始终使用模块名ClassMethods来保存任何类方法

但是,下面的工作(在A中)-它基本上检测基本模块是否定义了ClassMethods。如果是这样,它会将A的类方法添加到基类方法中。如果没有,它将在基中创建一个ClassMethods模块(克隆a的类方法)

 def self.included(base)
    extend ClassMethods

    if base.kind_of? Module  
      if  base.include? ClassMethods
         base::ClassMethods.extend(ClassMethods)
      else 
         base.const_set(:ClassMethods, ClassMethods)
         base.module_eval('def self.included(klass);klass.extend(ClassMethods.clone);end') 
      end
    end
  end