繁体   English   中英

Ruby模块类方法继承

[英]Ruby Module Class Methods inheritance

您如何使在嵌套模块系列中定义的类方法沿模块混合树传播?

考虑以下:

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类包含B,它也不会继承A中定义的类方法。

B class methods:   [:bar]
B instance methods [:foo]
C class methods:   []
C instance methods [:foo]

有没有一种整洁的方法来确保A中的类方法向上传播到C中(所以我可以称呼C.bar)? 我正在寻找一种不错的通用方法,该方法不涉及专门针对每个继承的模块调用和扩展C。

亲切的问候

史蒂夫

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

module B
  include A

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

或者,您可以将B定义为一个class并让C继承它。 我想这全都取决于您的设计以及您要实现的目标。

好-我知道了。 这是一个小技巧,因为它始终依赖于模块层次结构,该层次结构始终使用模块名称ClassMethods来保存任何Class Methods。

但是,以下工作(在A中)-它基本上检测基本模块是否已定义ClassMethods。 如果是这样,它将A的Classmethods添加到基本ClassMethods。 如果不是,它将在基础中创建一个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM