7

I was working on my web-application and I wanted to override a method for example if the original class is

class A
  def foo
    'original'
  end
end

I want to override foo method it can be done like this

class A
  alias_method :old_foo, :foo
  def foo
    old_foo + ' and another foo'
  end
end

and I can call both old and new methods like this

obj = A.new
obj.foo  #=> 'original and another foo'
obj.old_foo #=> 'original'

so what is the use of alias_method_chain if I can access and keep both methods like the way I did ?

H.Elsayed
  • 431
  • 2
  • 11

1 Answers1

9

alias_method_chain behaves different than alias_method

If you have method do_something and you want to override it, keeping the old method, you can do:

alias_method_chain :do_something, :something_else

which is equivalent to:

alias_method :do_something_without_something_else, :do_something
alias_method :do_something, :do_something_with_something_else

this allows us to easily override method, adding for example custom logging. Imagine a Foo class with do_something method, which we want to override. We can do:

class Foo
  def do_something_with_logging(*args, &block)
    result = do_something_without_logging(*args, &block)
    custom_log(result)
    result
  end
  alias_method_chain :do_something, :logging
end

So to have your job done, you can do:

class A
  def foo_with_another
    'another foo'
  end
  alias_method_chain :foo, :another
end
a = A.new
a.foo # => "another foo"
a.foo_without_another # => "original"

Since it isn't very complicated, you can also do it with plain alias_method:

class A
  def new_foo
    'another foo'
  end
  alias_method :old_foo, :foo
  alias_method :foo, :new_foo
end
a = A.new
a.foo # => "another foo"
a.old_foo # => "original"

For more information, you can refer documentation.

Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
  • 1
    This is a good explanation for `alias_method_chain` but i think the question is a little bit different. – M.ElSaka May 13 '14 at 10:44
  • Thanks ,but this is what alias_method_chain done , what i'm asking is if I can do it with alias_method like my example what is the real difference then between the two ways ? – H.Elsayed May 13 '14 at 10:46
  • @user1651643 if you want to preserve `old_foo` name to the 'old' method, then no, you can't do it with `alias_method_chain`. – Marek Lipka May 13 '14 at 10:48
  • @MarekLipka that's mean that there are no differences between the two ways and alias_method_chain doesn't add new things ? – H.Elsayed May 13 '14 at 10:53
  • 1
    @helsayed yes. All `alias_method_chain` is doing in this case is `alias_method :foo_without_another, :foo` and `alias_method :foo, :foo_with_another`. – Marek Lipka May 13 '14 at 10:54