Hi all,
I have a mixin module that needs to redefine a particular method if it already exists and retain a reference to it for later use. This is what I came up with:
module Example
def Example.included(klass)
if klass.instance_methods.include? "look_inside"
klass.instance_eval { alias_method :old_look_inside, :look_inside }
klass.send(:define_method, :look_inside) { |event|
#use old_look_inside in here
}
end
end
end
Is there a better/different way of doing this? (This works, I'm just curious).
-Justin
Justin Collins wrote:
Hi all,
I have a mixin module that needs to redefine a particular method if it already exists and retain a reference to it for later use. This is what I came up with:
module Example
def Example.included(klass)
if klass.instance_methods.include? "look_inside"
klass.instance_eval { alias_method :old_look_inside, :look_inside }
klass.send(:define_method, :look_inside) { |event|
#use old_look_inside in here
}
end
end
end
Is there a better/different way of doing this? (This works, I'm just curious).
I'd say you should alias the module's method, not the original class' method, because otherwise class hierarchy issues could get confusing. How should a subclass behave, for example?
Anyway, I wrote the 'use' package specifically to deal with this situation:
class Foo
include Example, :alias => {:look_inside, :example_look_inside}
end
Your other option is to adopt a simple naming convention for your modules, where all methods from the Example module start with 'example_' (for example), and avoid the entire issue altogether.
Regards,
Dan
Daniel Berger wrote:
Justin Collins wrote:
Hi all,
I have a mixin module that needs to redefine a particular method if it already exists and retain a reference to it for later use. This is what I came up with:
module Example
def Example.included(klass)
if klass.instance_methods.include? "look_inside"
klass.instance_eval { alias_method :old_look_inside, :look_inside }
klass.send(:define_method, :look_inside) { >event>
#use old_look_inside in here
}
end
end
end
Is there a better/different way of doing this? (This works, I'm just curious).
I'd say you should alias the module's method, not the original class' method, because otherwise class hierarchy issues could get confusing. How should a subclass behave, for example?
Anyway, I wrote the 'use' package specifically to deal with this situation:
class Foo
include Example, :alias => {:look_inside, :example_look_inside}
end
Your other option is to adopt a simple naming convention for your modules, where all methods from the Example module start with 'example_' (for example), and avoid the entire issue altogether.
Regards,
Dan
Hi Dan,
The module should only provide this new method if the class that is including it has it. In other words, I need to wrap the method call in some logic when this module is included. The module does not provide the method if the class that mixes in the module does not have the existing method. I haven't seen a way of doing the alias in the module that will accomplish this. I'm not sure using a naming convention would help in this particular case, because it should be transparent to any outside calls to the method.
As far as subclassing (subclassing the class which mixes in the module?), it should retain the behavior provided in the module.
Thanks.
-Justin