Overloading a module method?

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

module Math
   def Math.cos val
     if val.kind_of? MyType
       val = super(val)
       # do stuff with val and return
       return val
     else
       # normal behavior
       super
     end
   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

Hi --

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

module Math
def Math.cos val
   if val.kind_of? MyType
     val = super(val)
     # do stuff with val and return
     return val
   else
     # normal behavior
     super
   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.

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

etc.

David

···

On Thu, 9 Dec 2004, Dominik Werder wrote:

--
David A. Black
dblack@wobblini.net

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.

   class << Math # operate on Math's singleton superclass
     alias :oldcos :cos
     def cos(val)
       # 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 :frowning: 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

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
   unless const_defined? :T # I may not do this twice, otherwise I loose the original
     puts "Aliasing"
     T=true
     alias :sino :sin # preserving the original
     module_function :sino # required if I want to call sino from within Math.sin
   end
   def sin x # here goes my new sin where I still use the old one
     if x.kind_of? Wert
       W.abs sino(x.v), coso(x.v)*x.e
     else
       sino x
     end
   end
   module_function :sin # make it available as Math.sin too
end

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.

   class << Math # operate on Math's singleton superclass
     alias :oldcos :cos
     def cos(val)
       # 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 :frowning: This is bad because I dont really want to rewrite the other scripts.

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

HTH,

Zach

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
   alias :sino :sin
   module_function :sino
   def sin( x )
     sino( x )
   end
   module_function :sin
end

def test1
   include Math
   puts sin( 1 )
end

def test2
   include Math
   puts sin( 2 )
end

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

test1
test2

···

------
Zach

module Math
  class << self
    alias :oldcos :cos
  end
  def Math::cos( val )
    #etc...
  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

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

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

=)

Zach

To get it to work across the board:

module Math
  class << self
    alias :oldcos :cos
  end
  alias :oldcos :cos
  def cos( val )
   puts oldcos( val );
   "here";
  end
  module_function :cos
end

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

HTH,

Zach