Alias method in module

D

Dagnan

Hi.

I'm trying to alias a method in a module and then overwriting this method (still having access to the old method).

I tried the following code that does not seem to work with Ruby 1.9.2. Do you have an idea why?

Thanks.

class A
def foo
puts 'bar'
end
end

module Foo
def self.included(base)
base.class_eval do
alias_method :eek:ld_foo, :foo #unless method_defined?:)old_foo)
end
end

def foo
puts 'foobar'
#old_foo
end
end

A.send :include, Foo

a = A.new
a.foo #=> bar
 
B

botp

I'm trying to alias a method in a module and then overwriting this method (still having access to the old method).

try

class A
def foo
puts 'bar'
end
end

module Foo
def self.included(base)
base.class_eval do
alias_method :eek:ld_foo, :foo #unless method_defined?:)old_foo)
end
end


def initialize(*args)
self.extend Foo::Overrider
end

module Overrider
def foo
puts 'foobar'
#old_foo
end
end


end

A.send :include, Foo

a = A.new
a.foo #=> foobar
a.old_foo #=>bar

not just sure if that is the best way for modifying a class instance
methods. i'd rather just use require if possible ...

best regards -botp
 
B

Brian Candler

Looks like when you include module Foo, the definition of foo in the
class still takes precedence over the one in the newly-included module.

This seems to work though:

class A
def foo
puts 'bar'
end
end

module Foo
def self.included(base)
base.class_eval do
alias_method :eek:ld_foo, :foo
def foo
puts 'foobar'
old_foo
end
end
end
end

A.send :include, Foo

a = A.new
a.foo
 
S

Su Zhang

As of Ruby 1.9, when you include a module M in a class C, an anonymous
class is created and becomes the immediate superclass of C and subclass
of C's original superclass. All instance methods of M will be inherited
by C in the same old way. So it is actually M#foo who gets overridden
(by its subclass C#foo); C#foo never gets redefined. This is how Ruby
currently resolves name conflicts raised during mixin.

If you call `super' in C#foo, it will route to M#foo.

class A
def foo
puts 'bar'
super
end
end

module Foo
def foo
puts 'foobar'
end
end

A.send :include, Foo

a = A.new
a.foo # => bar\nfoobar
 
B

Brian Candler

Su Zhang wrote in post #978699:
class A
def foo
puts 'bar'
super
end
end

module Foo
def foo
puts 'foobar'
end
end

A.send :include, Foo

a = A.new
a.foo # => bar\nfoobar

It's the same in 1.8.7.

I think the OP was looking for a way to achieve the opposite behaviour:
to import a module which would override the method in the class.
 
A

Adam Prescott

[Note: parts of this message were removed to make it a legal post.]

I think the OP was looking for a way to achieve the opposite behaviour:
to import a module which would override the method in the class.

John Mair (banisterfiend) has written some code to manipulate ancestor
chains, two of which are Remix and Prepend:

Remix: https://github.com/banister/remix
Prepend: https://github.com/banister/prepend

Prepend should do exactly what you're looking for.
 

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
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top