# Overloading a module method?

**URL:** <https://rubytalk.org/t/overloading-a-module-method/15213>\
**Category:** ruby-talk\
**Created:** [8 December 2004 19:32 UTC](https://rubytalk.org/t/overloading-a-module-method/15213 "2004-12-08T19:32:29Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dominik\_Werder2](https://avatars.discourse-cdn.com/v4/letter/d/fbc32d/32.png) [@Dominik\_Werder2](https://rubytalk.org/u/Dominik_Werder2)\
**Post date:** [8 December 2004 19:32 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/1 "2004-12-08T19:32:29Z")

</div>

I'm having a headache while trying to achive something like this:

module Math  
&nbsp;&nbsp;&nbsp;def Math.cos val  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if val.kind\_of? MyType  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = super(val)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do stuff with val and return  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return val  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# normal behavior  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
end

super seems not to work, perhaps because Math is not a module..

Does anybody please know how to to this?

thanks and bye!  
Dominik

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [8 December 2004 19:51 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/2 "2004-12-08T19:51:21Z")

</div>

Hi --

> I'm having a headache while trying to achive something like this:
> 
> module Math  
> def Math.cos val  
> &nbsp;&nbsp;&nbsp;if val.kind\_of? MyType  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = super(val)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do stuff with val and return  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return val  
> &nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# normal behavior  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
> &nbsp;&nbsp;&nbsp;end  
> end  
> end
> 
> super seems not to work, perhaps because Math is not a module..
> 
> Does anybody please know how to to this?

I think what you want is to alias the old method. super takes you up  
the method lookup chain, whereas alias operates at the same level but  
moves laterally, so to speak.

&nbsp;&nbsp;&nbsp;class \<\< Math # operate on Math's singleton superclass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def cos(val)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# here, oldcos(val) will call the old cos

etc.

David

> **···**
>
> On Thu, 9 Dec 2004, Dominik Werder wrote:
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![Dominik\_Werder2](https://avatars.discourse-cdn.com/v4/letter/d/fbc32d/32.png) [@Dominik\_Werder2](https://rubytalk.org/u/Dominik_Werder2)\
**Post date:** [9 December 2004 19:22 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/3 "2004-12-09T19:22:28Z")

</div>

> I think what you want is to alias the old method. super takes you up  
> the method lookup chain, whereas alias operates at the same level but  
> moves laterally, so to speak.
> 
> &nbsp;&nbsp;&nbsp;class \<\< Math # operate on Math's singleton superclass  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def cos(val)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# here, oldcos(val) will call the old cos

this works basically, thanks, but it has some limitations:

I can call the new method now with Math.cos, but: If an other script includes Math, then not the modified proxy class will be included but the original module, so I loose all the new stuff ☹ This is bad because I dont really want to rewrite the other scripts.

Second, a minor issue compared to the first, is that I have to watch not to load my code twice, otherwise I overwrite my alias and the original cos is lost..

I try hard to figure out how to make it better, but it seems that I'm stuck..

bye!  
Dominik

---

<div class="post-metadata">

**Author:** ![Dominik\_Werder2](https://avatars.discourse-cdn.com/v4/letter/d/fbc32d/32.png) [@Dominik\_Werder2](https://rubytalk.org/u/Dominik_Werder2)\
**Post date:** [9 December 2004 20:07 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/4 "2004-12-09T20:07:27Z")

</div>

I found some things on the path to the solution that I wanted to share. I'm not yet entirely happy with this code because I still have to watch to not "load 'mymath.rb'" it twice, anyway..  
One important thing I learned: module functions are much different from normal methods you can define within a module..

module Math  
&nbsp;&nbsp;&nbsp;unless const\_defined? :T # I may not do this twice, otherwise I loose the original  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "Aliasing"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T=true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias :sino :sin # preserving the original  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module\_function :sino # required if I want to call sino from within Math.sin  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def sin x # here goes my new sin where I still use the old one  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if x.kind\_of? Wert  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;W.abs sino(x.v), coso(x.v)\*x.e  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sino x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;module\_function :sin # make it available as Math.sin too  
end

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [9 December 2004 20:09 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/5 "2004-12-09T20:09:31Z")

</div>

Dominik Werder wrote:

> > I think what you want is to alias the old method. super takes you up  
> > the method lookup chain, whereas alias operates at the same level but  
> > moves laterally, so to speak.
> > 
> > &nbsp;&nbsp;&nbsp;class \<\< Math # operate on Math's singleton superclass  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def cos(val)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# here, oldcos(val) will call the old cos
> 
> this works basically, thanks, but it has some limitations:
> 
> I can call the new method now with Math.cos, but: If an other script includes Math, then not the modified proxy class will be included but the original module, so I loose all the new stuff ☹ This is bad because I dont really want to rewrite the other scripts.

module Math  
&nbsp;&nbsp;class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
&nbsp;&nbsp;end  
&nbsp;&nbsp;def Math::cos( val )  
&nbsp;&nbsp;&nbsp;&nbsp;#etc...  
&nbsp;&nbsp;end  
end

HTH,

Zach

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [10 December 2004 00:06 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/6 "2004-12-10T00:06:53Z")

</div>

Dominik Werder wrote:

> I found some things on the path to the solution that I wanted to share. I'm not yet entirely happy with this code because I still have to watch to not "load 'mymath.rb'" it twice, anyway..

I dont see why you have to do this. Unless I understand you wrong I do not get the problem. For example:

module Math  
&nbsp;&nbsp;&nbsp;alias :sino :sin  
&nbsp;&nbsp;&nbsp;module\_function :sino  
&nbsp;&nbsp;&nbsp;def sin( x )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sino( x )  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;module\_function :sin  
end

def test1  
&nbsp;&nbsp;&nbsp;include Math  
&nbsp;&nbsp;&nbsp;puts sin( 1 )  
end

def test2  
&nbsp;&nbsp;&nbsp;include Math  
&nbsp;&nbsp;&nbsp;puts sin( 2 )  
end

include Math  
puts sin( 3 )  
puts Math::sin( 4 )  
puts Math.sin( 5 )

test1  
test2

> **···**
>
> ------  
> Zach

---

<div class="post-metadata">

**Author:** ![Dominik\_Werder2](https://avatars.discourse-cdn.com/v4/letter/d/fbc32d/32.png) [@Dominik\_Werder2](https://rubytalk.org/u/Dominik_Werder2)\
**Post date:** [9 December 2004 20:47 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/7 "2004-12-09T20:47:27Z")

</div>

> module Math  
> &nbsp;&nbsp;class \<\< self  
> &nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
> &nbsp;&nbsp;end  
> &nbsp;&nbsp;def Math::cos( val )  
> &nbsp;&nbsp;&nbsp;&nbsp;#etc...  
> &nbsp;&nbsp;end  
> end

if I do it this way and load this code in irb, I can do:

Math.cos 2

but not:

include Math  
cos 2

this would invoke the original cos method..

but see my other posting where I have already solved this part :))

thanks anyway!  
Dominik

---

<div class="post-metadata">

**Author:** ![Dominik\_Werder2](https://avatars.discourse-cdn.com/v4/letter/d/fbc32d/32.png) [@Dominik\_Werder2](https://rubytalk.org/u/Dominik_Werder2)\
**Post date:** [10 December 2004 12:07 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/8 "2004-12-10T12:07:26Z")

</div>

> > I found some things on the path to the solution that I wanted to share. I'm not yet entirely happy with this code because I still have to watch to not "load 'mymath.rb'" it twice, anyway..
> 
> I dont see why you have to do this. Unless I understand you wrong I do not get the problem. For example:

Yes, this works perfectly as long as you don't "load" the module definition twice accidentally. Otherwise the old sin method gets lost. Try it, paste your module definition twice into irb and try to call it.  
But thats just a minor issue, because I can keep track by a flag. I have to do this because some scripts use load instead of require, so it happens that the code is loaded twice..

bye and thank you!  
Dominik

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [9 December 2004 21:00 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/9 "2004-12-09T21:00:48Z")

</div>

module Math  
&nbsp;&nbsp;class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
&nbsp;&nbsp;end  
&nbsp;&nbsp;def cos( val ); "here"; end  
&nbsp;&nbsp;module\_function :cos  
end  
&nbsp;&nbsp;&nbsp;&nbsp;  
include Math  
puts Math::cos( 5 )  
puts cos( 5 )

=)

Zach

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [9 December 2004 21:02 UTC](https://rubytalk.org/t/overloading-a-module-method/15213/10 "2004-12-09T21:02:57Z")

</div>

To get it to work across the board:

module Math  
&nbsp;&nbsp;class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;alias :oldcos :cos  
&nbsp;&nbsp;end  
&nbsp;&nbsp;alias :oldcos :cos  
&nbsp;&nbsp;def cos( val )  
&nbsp;&nbsp;&nbsp;puts oldcos( val );  
&nbsp;&nbsp;&nbsp;"here";  
&nbsp;&nbsp;end  
&nbsp;&nbsp;module\_function :cos  
end

include Math  
puts Math::cos( 5 )  
puts cos( 5 )

HTH,

Zach
