1 - он все еще используется?
Очевидно, да, alias_method_chain()
все еще используется в Rails (начиная с версии 3.0.0).
2 - когда бы вы использовали alias_method_chain и почему?
( Примечание: следующее в значительной степени основано на обсуждении alias_method_chain()
in Metaprogramming Ruby от Paolo Perrotta, которая является прекрасной книгой, которую вы должны получить. )
Давайте начнем с базового примера:
class Klass
def salute
puts "Aloha!"
end
end
Klass.new.salute # => Aloha!
Теперь предположим, что мы хотим окружить Klass#salute()
поведением логирования.Мы можем сделать то, что Perrotta называет вокруг псевдонима :
class Klass
def salute_with_log
puts "Calling method..."
salute_without_log
puts "...Method called"
end
alias_method :salute_without_log, :salute
alias_method :salute, :salute_with_log
end
Klass.new.salute
# Prints the following:
# Calling method...
# Aloha!
# ...Method called
Мы определили новый метод с именем salute_with_log()
и присвоили ему псевдоним salute()
.Код, который раньше вызывал salute()
, все еще работает, но он также получает новое поведение при ведении журнала.Мы также определили псевдоним для исходного salute()
, поэтому мы можем приветствовать его без регистрации:
Klass.new.salute_without_log # => Aloha!
Итак, salute()
теперь называется salute_without_log()
.Если нам нужна регистрация, мы можем вызвать либо salute_with_log()
, либо salute()
, которые являются псевдонимами одного и того же метода.Смущенный?Хорошо!
По словам Перротты, такой тип псевдонимов очень распространен в Rails:
Посмотрите на другой пример того, как Rails решает проблему по-своему.Несколько версий назад код Rails содержал много экземпляров той же идиомы: Around Alias (155) использовался для добавления функции к методу, а старая версия метода была переименована во что-то вродеmethod_without_feature()
.Помимо имен методов, которые менялись каждый раз, код, который делал это, всегда был одинаковым, везде дублировался.В большинстве языков вы не можете избежать такого дублирования.В Ruby вы можете разбрызгивать магию метапрограммирования над вашим шаблоном и извлекать его в свой собственный метод ... и, таким образом, он родился alias_method_chain()
.
Другими словами, вы предоставляете оригинальный метод foo()
, и расширенный метод foo_with_feature()
, и в итоге вы получите три метода: foo()
, foo_with_feature()
и foo_without_feature()
.Первые два включают функцию, а третье нет.Вместо дублирования этих псевдонимов alias_method_chain()
, предоставляемый ActiveSupport , сделает все за вас.