Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between alias_method and alias_method_chain?

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 ?

like image 919
H.Elsayed Avatar asked May 13 '14 10:05

H.Elsayed


1 Answers

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.

like image 70
Marek Lipka Avatar answered Sep 28 '22 13:09

Marek Lipka