获取包含模块的类列表 [英] Getting a list of classes that include a module

查看:27
本文介绍了获取包含模块的类列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 mixin,我想获取包含它的所有类的列表.在mixin模块中,我做了以下事情:

I have a mixin for which I would like to get a list of all the classes that have included it. In the mixin module, I did the following:

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"]

现在,我想将这部分提取到一个单独的模块中,该模块可以包含在我的其他 mixin 中.所以,我想出了以下内容:

Now, I would like to extract this part out into a separate module that can be included in my other mixins. So, I came up with the following:

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.

This doesn't work though, because the #included(module_base) method being added to MyModule from ListIncludedClasses is never getting run. Interestingly enough, it does successfully add #classes to 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

我错过了什么?

推荐答案

module MyMod; end

class A; include MyMod; end
class B < A; end
class C; end

ObjectSpace.each_object(Class).select { |c| c.included_modules.include? MyMod }
  #=> [B, A]

这篇关于获取包含模块的类列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆