[英]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.