Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell what modules have been mixed into a class?

Tags:

ruby

I have a class that has a number of modules that are mixed in with it based on some runtime criteria.

I want to be able to get a list of which modules have been mixed into this class. How can you do that?

UPDATE

So when I said class I meant object as it is the object that is being extended at runtime using:

obj.extend(MyModule) 

obj.included_modules and obj.ancestors don't exist so you can't get the modules that have been mixed in from there.

like image 473
Derek Ekins Avatar asked Aug 25 '09 12:08

Derek Ekins


People also ask

What is the relationship between classes and modules?

Classes may generate instances (objects), and have per-instance state (instance variables). Modules may be mixed in to classes and other modules. The mixed in module's constants and methods blend into that class's own, augmenting the class's functionality. Classes, however, cannot be mixed in to anything.

Is module and class the same?

Modules are about providing methods that you can use across multiple classes - think about them as "libraries" (as you would see in a Rails app). Classes are about objects; modules are about functions. For example, authentication and authorization systems are good examples of modules.

Can modules include other modules Ruby?

Actually, Ruby facilitates the use of composition by using the mixin facility. Indeed, a module can be included in another module or class by using the include , prepend and extend keywords.

Why do we use modules in class?

A module facilitates code reusability since you can define a function in a module and invoke it from different programs instead of having to define the function in every program. Although a module is mostly used for function and class definitions, it may also export variables and class instances.


1 Answers

Try:

MyClass.ancestors.select {|o| o.class == Module } 

for example:

>> Array.ancestors.select {|o| o.class == Module} => [Enumerable, Kernel] 

UPDATE

To get the modules mixed into an object instance at runtime you'll need to retrieve the eigenclass of the instance. There is no clean way to do this in Ruby, but a reasonably common idiom is the following:

(class << obj; self; end).included_modules 

If you find yourself using this a lot, you can make it generally available:

module Kernel   def eigenclass     class << self       self     end   end end 

and the solution is then:

obj.eigenclass.included_modules 
like image 98
Daniel Lucraft Avatar answered Sep 21 '22 17:09

Daniel Lucraft