本文介绍了Ruby on Rails:alias_method_chain,它到底是做什么的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试通读各种博客文章,试图解释 alias_method_chain 以及使用和不使用它的原因.我特别注意:

I've tried reading through various blog posts that attempt to explain alias_method_chain and the reasons to use it and not use it. In particular, I took heed to:

http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain

http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/

我仍然没有看到 alias_method_chain 的任何实际用途.谁能解释一下.

I still do not see any practical use for alias_method_chain. Would anyone be able to explain a few things.

1 - 它还在使用吗?
2 - 你什么时候会使用 alias_method_chain 以及为什么?

1 - is it still used at all?
2 - when would you use alias_method_chain and why?

推荐答案

显然是的,alias_method_chain()仍在 Rails 中使用(从 3.0.0 版开始).

Apparently yes, alias_method_chain() is still used in Rails (as of version 3.0.0).

2 - 你什么时候使用alias_method_chain 以及为什么?

(注意:以下主要基于,这是一本您应该亲自动手的好书.)

(Note: the following is largely based on the discussion of alias_method_chain() in Metaprogramming Ruby by Paolo Perrotta, which is an excellent book that you should get your hands on.)

让我们从一个基本的例子开始:

Let's start with a basic example:

class Klass
  def salute
    puts "Aloha!"
  end
end

Klass.new.salute # => Aloha!

现在假设我们想用日志记录行为包围 Klass#salute().我们可以做到 Perrotta 所说的周围别名:

Now suppose that we want to surround Klass#salute() with logging behavior. We can do that what Perrotta calls an around alias:

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() 定义了一个别名,所以我们仍然可以不记录就行礼:

We defined a new method called salute_with_log() and aliased it to salute(). The code that used to call salute() still works, but it gets the new logging behavior as well. We also defined an alias to the original salute(), so we can still salute without logging:

Klass.new.salute_without_log # => Aloha!

所以,salute() 现在被称为 salute_without_log().如果我们想记录日志,我们可以调用 salute_with_log()salute(),它们是相同方法的别名.使困惑?不错!

So, salute() is now called salute_without_log(). If we want logging, we can call either salute_with_log() or salute(), which are aliases of the same method. Confused? Good!

据 Perrotta 所说,这种环绕别名在 Rails 中很常见:

According to Perrotta, this kind of around alias is very common in 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 提供 为您完成所有别名操作.

In other words, you provide the original method, foo(), and the enhanced method, foo_with_feature(), and you end up with three methods: foo(), foo_with_feature(), and foo_without_feature(). The first two include the feature, while the third doesn't. Instead of duplicating these aliases all around, alias_method_chain() provided by ActiveSupport does all the aliasing for you.

这篇关于Ruby on Rails:alias_method_chain,它到底是做什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 05:25