views:

56

answers:

3

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

and

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

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

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

+1  A: 

I'm not sure if it's gone out of style with Rails 3 or not, but it is still actively used in versions before that.

You use it to inject some functionality before (or after) a method is called, without modifying any place that calls that method. See this example:

module SwitchableSmtp
  module InstanceMethods
    def deliver_with_switchable_smtp!(mail = @mail)
      unless logger.nil?
        logger.info  "Switching SMTP server to: #{custom_smtp.inspect}" 
      end
      ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil?
      deliver_without_switchable_smtp!(mail = @mail)
    end
  end
  def self.included(receiver)
    receiver.send :include, InstanceMethods
    receiver.class_eval do
      alias_method_chain :deliver!, :switchable_smtp
    end
  end
end

That's an addition to ActionMailer to allow swapping out of the SMTP settings on each call to deliver!. By calling alias_method_chain you are able to define a method deliver_with_switchable_smtp! in which you do your custom stuff, and call deliver_without_switchable_smtp! from there when you're done.

alias_method_chain aliases the old deliver! to your new custom method, so the rest of your app doesn't even know deliver! now does your custom stuff too.

tfe
+1  A: 
Yaser Sulaiman
A: 

is it used at all?

Seems so. It's a common practice among Rails developers

when would you use alias_method_chain and why?

Despite the warnings, alias_method_chain is still the main strategy used when injecting functionality to an existing method, at least was in Rails 2.x and is followed by many people extending it. Yehuda ought to remove alias_method_chain from rails 3.0 to say from his posts and comments in Rails tickets. It is still used by many extensions that add custom behavior at certain points of the execution, such as loggers, error reporters, benchmarking, data injection, etc.

IMO, the best alternative is to include a module, thus you have decoration over delegation. (For example, follow example 4 in this post). That way you can alter the objects even individually if you'd like, without polluting the class' methods. The downside to this is that the method lookup chain increases for each module you inject, but this is what modules are for anyway.

Very interesting question, will keep a look on what other people think about it.

Chubas