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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With