В чем разница между alias_method и alias_method_chain?

Я работал над своим веб-приложением и хотел переопределить метод, например, если исходный класс

class A
  def foo
    'original'
  end
end

Я хочу переопределить метод foo, это можно сделать так

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

и я могу вызвать как старые, так и новые методы, как это

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

Так какая польза от alias_method_chain, если я могу получить доступ к обоим методам и сохранить их, как я сделал?

1 ответ

alias_method_chain ведет себя иначе, чем alias_method

Если у вас есть метод do_something и вы хотите переопределить его, сохранив старый метод, вы можете сделать:

alias_method_chain :do_something, :something_else

что эквивалентно:

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

это позволяет нам легко переопределить метод, добавив, например, настраиваемое ведение журнала. Представь себе Foo класс с do_something метод, который мы хотим переопределить. Мы можем:

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

Итак, чтобы ваша работа была выполнена, вы можете сделать:

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"

Поскольку это не очень сложно, вы также можете сделать это с простым 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"

Для получения дополнительной информации вы можете обратиться к документации.

Другие вопросы по тегам