Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an alias_method for a class method? [duplicate]

Consider the following class:

class Foo
  def an_inst_method
    'instance method'
  end

  def self.a_class_method
    'class method'
  end

  alias_method :a_new_inst_method, :an_inst_method
end

This is no issue and you can call Foo.new.a_new_inst_method with no issue.

I'd like the ability to have a class method like Foo.add_widget(*items) and alias it so I can do something like:

Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'

So essentially it has a "ruby style" like 1.minute and 2.minutes so I want to alias a Foo.add_widget so calling Foo.add_widgets calls the exact same method. I know I could wrap it but I feel like I should be able to do this in a cleaner fashion.

Consider my attempt at trying something like this:

class Foo
  def an_inst_method
    'instance method'
  end

  def self.a_class_method
    'class method'
  end

  alias_method :a_new_inst_method, :an_inst_method
  alias_method :a_new_class_method, :a_class_method
end

However, I get the following error:

NameError (undefined method `a_class_method' for class `Foo')

And so it looks like this doesn't work for class methods. How do I go about doing this?

like image 510
aarona Avatar asked Apr 20 '20 19:04

aarona


1 Answers

alias_method aliases an instances method of the receiver. Class methods are actually instance methods defined on the singleton class of a class.

class MyClass
  def self.a
    "Hello World!"
  end
end

method_1 = MyClass.method(:a).unbind
method_2 = MyClass.singleton_class.instance_method(:a)

method_1 == method_2
#=> true

To alias an instance method defined on the singleton class you can either open it up using the class << object syntax.

class << MyClass
  alias_method :b, :a
end

MyClass.b
#=> "Hello World!"

Or you can refer to it directly using the singleton_class method.

MyClass.singleton_class.alias_method :c, :a

MyClass.c
#=> "Hello World!"

If you are still within the class context self will refer to the class. So the above could also be written as:

class MyClass
  class << self
    def a
      "Hello World!"
    end
    alias_method :b, :a
  end
end

Or

class MyClass
  def self.a
    "Hello World!"
  end
  singleton_class.alias_method :c, :a
end

Or a combination of the two.

like image 142
3limin4t0r Avatar answered Oct 03 '22 03:10

3limin4t0r