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

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

···

On Fri, Jan 28, 2011 at 10:45 PM, Dagnan <dagnan@gmail.com> wrote:

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

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

···

--
Posted via http://www.ruby-forum.com/.

Thank you all for your answers.

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

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

···

--
Posted via http://www.ruby-forum.com/.

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.

···

--
Posted via http://www.ruby-forum.com/\.

John Mair (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.

···

On Mon, Jan 31, 2011 at 6:06 PM, Brian Candler <b.candler@pobox.com> 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.