如何在嵌套的模块系列中定义类方法在模块mixin树中向上传播?
请考虑以下事项:
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语言。
亲切的问候
史蒂夫
答案 0 :(得分:0)
如果您不想手动延长ClassMethods
,并且您希望任何人B
将其类界面扩展为ClassMethods
,那么您可以这样做:
module B
include A
def self.included(base)
base.extend(ClassMethods)
end
end
或者您可以将B
定义为class
并让C
继承自{{1}}。我想这一切都取决于你的设计以及你想要达到的目的。
答案 1 :(得分:0)
但是,以下工作(在A中) - 它基本上检测基本模块是否定义了ClassMethods。如果是这样,它会将A类的方法添加到基类ClassMethods。如果没有,它会在基础中创建一个ClassMethods模块(克隆A&#39的类方法)
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