Reputation: 20948
I have a module that add class methods when included into a class.
I would like to force this module to extend new methods by writing another module that will be included by the first one.
The following code gives an example of what i want to do that does not work : It would be great to be able to override the "self.included" function of the first module to extend the base with my methods.
So far I was able to override the self.included function of the first module but calling super does not work so I loose the class methods of the first module :
module SomeModule
def self.included(base)
base.send(:extend, ClassMethods)
end
module ClassMethods
# Some methods
end
end
module MyNewModule
def self.included(base)
base.class_eval do
def self.included(base)
base.send(:extend, ClassMethods)
super(base)
end
end
end
module ClassMethods
def my_method
end
end
end
SomeModule.send(:include, MyNewModule)
class Pouet
include SomeModule
my_method # undefined local variable or method `my_method' for Pouet:Class (NameError)
end
Is this possible?
Upvotes: 2
Views: 2775
Reputation: 20948
Finally managed to make it work by myself.
Please tell me if this is a good or a bad practice :
module SomeModule
def self.included(base)
base.send(:extend, ClassMethods)
end
module ClassMethods
def my_original_method
end
# Some methods
end
end
module MyNewModule
def self.included(base)
base.class_eval do
class << self
alias_method :old_included, :included
def included(base)
old_included(base)
base.send(:extend, ClassMethods)
end
end
end
end
module ClassMethods
def my_method
end
end
end
SomeModule.send(:include, MyNewModule)
class Pouet
include SomeModule
my_original_method
my_method
end
Upvotes: 0
Reputation: 1836
Use instance_eval inside your included block.
Inside the instance_eval block, you have access to the object that are you including it in, so you should then be able to include your extra modules there.
EDIT:
You have to pass a string to instance_eval, because the block will store your current context.
For an example of where I've done similar: https://github.com/JoePym/UndergroundFootball/blob/master/app/models/player.rb#L14
Upvotes: 1