Overloading a module method?

D

Dominik Werder

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
 
D

David A. Black

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 :eek:ldcos :cos
def cos(val)
# here, oldcos(val) will call the old cos

etc.


David
 
D

Dominik Werder

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 :eek:ldcos :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 :( 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
 
D

Dominik Werder

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
 
Z

Zach Dennis

Dominik said:
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
class << self
alias :eek:ldcos :cos
end
def Math::cos( val )
#etc...
end
end

HTH,

Zach
 
D

Dominik Werder

module Math
class << self
alias :eek:ldcos :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
 
Z

Zach Dennis

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



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


=)

Zach
 
Z

Zach Dennis

To get it to work across the board:

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

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


HTH,

Zach
 
Z

Zach Dennis

Dominik said:
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
include Math
puts sin( 2 )
end

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

test1
test2
 
D

Dominik Werder

I found some things on the path to the solution that I wanted to
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top