alias_method: a confusing method name

In the class Module, there is a useful method called #alias_method. By the name of it, you would expect to be able to create an alias, that is, another way to call the same method using a different name for it. Well, this is not exactly true.

A typical usage of Module#alias_method is when you want to override a method, as in this example from Programming Ruby:

module Mod
alias_method :origExit, :exit
def exit(code=0)
print "Exiting with code #{code}\n"
origExit(code)
end
end
include Mod
exit(99)

will produce:

Exiting with code 99

My point is that if it would create a pure alias, both the original name and the newly created alias would refer to the exact same method, but that’s not what’s happening. The Module#alias_method method actually creates a copy of the method body. For example, if you’d override #origExit in the preceding example, you wouldn’t override #exit by the same token. #origExit and #exit are indeed two different entities of code.

This brings me to a nice add-on in Rails: Module#alias_method_chain, which provides for an easy way to decorate a method. As explained in this post, while the old way was to do something like that:

alias_method :render_without_feature, :render
alias_method :render, :render_with_feature

It is now possible to go like so:

alias_method_chain :method_name, :feature

Provided you defined your own method called #method_name_with_feature, from now on, each time you’ll have a call to #method_name, it will actually call method_name_with_feature behind the scenes. If you want the plain old behavior, you can still refer to it using #method_name_without_feature.

If you want a concrete example, you can have a look at the Validations module located at:
/var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb

where you can read:

alias_method_chain :save, :validation

which effectively adds a validation feature to the save method.

Advertisements

2 comments

  1. Not true.. alias works for this as well. Ex:module Kernel @@_require_num = 0 alias :test_original_require :require def require(name) puts “Requiring #{name} #{@@_require_num += 1}” test_original_require name endendrequire ‘rubygems’require ‘facets’require ‘rack’require ‘open-uri’results in:Requiring facets/unboundmethod/name.rb 447Requiring facets/unboundmethod.rb 448Requiring rack 449Requiring open-uri 450Requiring uri 451Requiring stringio 452Requiring time 453Requiring parsedate 454Requiring date/format 455….

  2. @Test
    The author didn't say anything about alias, but about alias_method. So your comment is quite off-topic.

Got a comment?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: