Alias method in module

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 :old_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

:

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 :old_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

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 :old_foo, :foo
def foo
puts ‘foobar’
old_foo
end
end
end
end

A.send :include, Foo

a = A.new
a.foo

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

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.

Thank you all for your answers.

Remix and Prepend have not been updated since a few months. candlerb and
bot Pea solution are interesting.

On Mon, Jan 31, 2011 at 6:06 PM, Brian C. [email protected]
wrote:

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 M. (banisterfiend) has written some code to manipulate ancestor
chains, two of which are Remix and Prepend:

Remix: GitHub - banister/remix: Ruby modules re-mixed and remastered
Prepend: GitHub - banister/prepend: prepends modules in front of a class; so method lookup starts with the module

Prepend should do exactly what you’re looking for.