Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a list of classes that include a module

Tags:

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 

This works pretty well:

> MyModule.classes #=> nil > MyClass.new #=> #<MyClass ...> > MyModule.classes #=> ["MyClass"] 

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 

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 

What am I missing?

like image 948
jangosteve Avatar asked Oct 12 '10 18:10

jangosteve


People also ask

Are classes and modules the same?

Classes are object-oriented, but modules are not. So only classes can be instantiated as objects.

How do I see classes in Python?

To get the class name of an instance in Python: Use the type() function and __name__ to get the type or class of the Object/Instance. Using the combination of the __class__ and __name__ to get the type or class of the Object/Instance.

Why do we use modules in class?

Modules allow instructors to organize content to help control the flow of the course. Modules are used to organize course content by weeks, units, or a different organizational structure.


2 Answers

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] 
like image 85
Cary Swoveland Avatar answered Oct 19 '22 16:10

Cary Swoveland


Actually, your module extension module works. The problem is in your test: when you created a random unnamed class with Class.new, you forgot to include MyModule. As a side note, you can take your read-only accessor for classes that include the module and use the helpful Module#attr_reader method.

like image 32
Aaa Avatar answered Oct 19 '22 15:10

Aaa