369

I found a blog post on alias vs. alias_method. As shown in the example given in that blog post, I simply want to alias a method to another within the same class. Which should I use? I always see alias used, but someone told me alias_method is better.

Usage of alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Usage of alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Blog post link here

philant
  • 34,748
  • 11
  • 69
  • 112
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 4
    Doesn't that post answer your question? – moinudin Jan 21 '11 at 19:55
  • 5
    @marcog: I've read it through, and I'm not convinced. Defining aliases inside methods, that's not something one should do often. – Boris Stitnicky Nov 03 '12 at 19:19
  • 2
    @digitalextremist link works – lukas.pukenis Sep 23 '13 at 09:31
  • 6
    The ruby style guide now recommends `alias` "when aliasing methods in lexical class scope" and `alias_method` "when aliasing methods of modules, classes, or singleton classes at runtime" https://github.com/bbatsov/ruby-style-guide#alias-method-lexically – jtzero Sep 22 '16 at 21:31

7 Answers7

388

alias_method can be redefined if need be. (it's defined in the Module class.)

alias's behavior changes depending on its scope and can be quite unpredictable at times.

Verdict: Use alias_method - it gives you a ton more flexibility.

Usage:

def foo
  "foo"
end

alias_method :baz, :foo
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
  • 47
    What do you mean by unpredictable. Naïvely, one would say that the option that is less flexible will be more predictable. Also, can you provide any practical example of benefitting from redefining alias_method? – Boris Stitnicky Nov 03 '12 at 19:17
  • 7
    example use case: `alias :new_method_name :old_method_name` OR `alias_method :new_method_name, :old_method_name` – boulder_ruby Dec 11 '12 at 00:28
  • 13
    The word he's looking for here is more **expected** results. `alias_method` is determined at runtime and not when the code is read, like `alias`, so it behaves more how we would **expect** it to. – Joshua Pinter Apr 22 '14 at 16:10
  • 4
    expecting that methods are defined on the fly during runtime is not what most programmers expect. At least it's like flying pigs to me. – akostadinov Jul 11 '14 at 21:20
  • akostadinov, I agree, although more flexible it certainly fails to follow the principle of least surprise. – ablarg Apr 22 '16 at 21:45
  • 16
    One could argue the same for `def` vs. `define_method`: "`define_method` can be redefined if need be. (it's defined in the `Module` class.) `def`'s behavior changes depending on its scope and can be quite unpredictable at times. Verdict: Use `define_method` - it gives you a ton more flexibility." – Daniel Rikowski Jan 10 '17 at 13:27
  • Never run for "flexibility" until it's impossible to avoid. One of the unwritten rules of good coding. – Nakilon Dec 05 '22 at 05:47
91

Apart from the syntax, the main difference is in the scoping:

# scoping with alias_method
class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias_method :name, :full_name
  end

end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Geeky geek'

In the above case method “name” picks the method “full_name” defined in “Developer” class. Now lets try with alias.

class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias name full_name
  end
end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Johnnie Walker'

With the usage of alias the method “name” is not able to pick the method “full_name” defined in Developer.

This is because alias is a keyword and it is lexically scoped. It means it treats self as the value of self at the time the source code was read . In contrast alias_method treats self as the value determined at the run time.

Source: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html

Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
Darme
  • 6,984
  • 5
  • 37
  • 52
39

A point in favor of alias instead of alias_method is that its semantic is recognized by rdoc, leading to neat cross references in the generated documentation, while rdoc completely ignore alias_method.

Bruno Rohée
  • 3,436
  • 27
  • 32
  • 60
    Maybe RDoc should start treating alias_method the same as alias. We should tell them about it ;) – Szymon Jeż Sep 02 '11 at 09:52
  • 9
    How is RDoc supposed to understand the consequences of a method that is evaluated at runtime? –  May 08 '14 at 09:03
  • 2
    @user1115652 Is your point that someone _might have_ monkey-patched `alias_method`? That seems _really_ unlikely, and if someone does that, then they should be willing to suffer the consequences in RDoc. If your point is that it's impossible, then why do you think that and how do you think Yardoc does it? – iconoclast Feb 11 '19 at 18:32
37

I think there is an unwritten rule (something like a convention) that says to use 'alias' just for registering a method-name alias, means if you like to give the user of your code one method with more than one name:

class Engine
  def start
    #code goes here
  end
  alias run start
end

If you need to extend your code, use the ruby meta alternative.

class Engine
  def start
    puts "start me"
  end
end

Engine.new.start() # => start me

Engine.class_eval do
  unless method_defined?(:run)
    alias_method :run, :start
    define_method(:start) do
      puts "'before' extension"
      run()
      puts "'after' extension"
    end
  end
end

Engine.new.start
# => 'before' extension
# => start me
# => 'after' extension

Engine.new.run # => start me
Nathan
  • 11,938
  • 12
  • 55
  • 62
agenty
  • 371
  • 3
  • 2
27

A year after asking the question comes a new article on the subject:

http://erniemiller.org/2014/10/23/in-defense-of-alias/

It seems that "so many men, so many minds." From the former article author encourages to use alias_method, while the latter suggests using alias.

However there's a common overview of these methods in both blogposts and answers above:

  • use alias when you want to limit aliasing to the scope where it's defined
  • use alias_method to allow inherited classes to access it
Jenner La Fave
  • 1,327
  • 1
  • 9
  • 11
Kamil Lelonek
  • 14,592
  • 14
  • 66
  • 90
20

The rubocop gem contributors propose in their Ruby Style Guide:

Prefer alias when aliasing methods in lexical class scope as the resolution of self in this context is also lexical, and it communicates clearly to the user that the indirection of your alias will not be altered at runtime or by any subclass unless made explicit.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Always use alias_method when aliasing methods of modules, classes, or singleton classes at runtime, as the lexical scope of alias leads to unpredictability in these cases

module Mononymous
  def self.included(other)
    other.class_eval { alias_method :full_name, :given_name }
  end
end

class Sting < Westerner
  include Mononymous
end
Nakilon
  • 34,866
  • 14
  • 107
  • 142
Doktor OSwaldo
  • 5,732
  • 20
  • 41
-1

alias_method new_method, old_method

old_method will be declared in a class or module which is being inherited now to our class where new_method will be used.

these can be variable or method both.

Suppose Class_1 has old_method, and Class_2 and Class_3 both of them inherit Class_1.

If, initialization of Class_2 and Class_3 is done in Class_1 then both can have different name in Class_2 and Class_3 and its usage.

Ajay
  • 1