我有一个mixin,我想获取所有已包含它的类的列表。在mixin模块中,我做了以下操作:
module MyModule
def self.included(base)
@classes ||= []
@classes << base.name
end
def self.classes
@classes
end
end
class MyClass
include MyModule
end
这个很好用:
> MyModule.classes #=> nil
> MyClass.new #=> #<MyClass ...>
> MyModule.classes #=> ["MyClass"]
现在,我想将这一部分提取出来成为一个单独的模块,可以包含在我的其他混合模块中。因此,我想出了以下代码:
module ListIncludedClasses
def self.included(base)
p "...adding #{base.name} to #{self.name}.classes"
@classes ||= []
@classes << base.name
base.extend(ClassMethods)
end
def self.classes
@classes
end
module ClassMethods
def included(module_base)
p "...adding #{module_base.name} to #{self.name}.classes"
@module_classes ||= []
@module_classes << module_base.name
super(module_base)
end
def classes
@module_classes
end
end
end
module MyModule
include ListIncludedClasses
end
然而这并不起作用,因为从ListIncludedClasses添加到MyModule的#included(module_base)方法从未运行。有趣的是,它确实成功地将#classes添加到了MyModule。
> MyModule.classes #=>
"...adding Rateable to ListIncludedClasses.classes"
=> nil
> ListIncludedClasses #=> ["MyModule"]
> MyClass.new #=> #<MyClass ...>
# ^^ THIS SHOULD BE ADDING MyClass TO MyModule.classes ^^
> MyModule.classes #=> nil
我错过了什么?