Class Alias in Ruby

Class alias in Ruby

Classes don't have names in Ruby. They are just objects assigned to variables, just like any other object. If you want to refer to a class via a different variable, assign it to a different variable:

Foo = String

Class name aliases in Ruby

Easy and simple:

Exit = Entrance

Classes in Ruby are really just objects of class Class that are assigned to constants with their name. So, just have a new constant refer to the same object as the old constant.

Note that now Exit and Entrance are the exact same class, and anything you do to one happens to the other:

2.0.0p0 :009 > Exit.object_id == Entrance.object_id
=> true

Note: While this is possible, I'd think more carefully about your general architecture. Is their any difference between an Entrance and an Exit? Are they both just really Doors? Your architecture should be such that classes won't (usually) need to be aliased unless you have two synonymous names that you really want to use both, like Page and WebPage (I'd recommend against this too).

How to alias a class method within a module?

You could use define_singleton_method to wrap your old method under a new name, like so:

module MyModule
def alias_class_method(new_name, old_name)
define_singleton_method(new_name) { old_name }
end
end

class MyClass
def my_method
puts "my method"
end
end

MyClass.extend(MyModule)
MyClass.alias_class_method(:my_new_method, :my_method)
MyClass.my_new_method # => "my method"

Answering your comment, you wouldn't have to extend every single class by hand. The define_singleton_method is implemented in the Object class. So you could simply extend the Object class, so every class should have the method available...

Object.extend(MyModule)

Put this in an initializer in your Rails app and you should be good to go...

Is there an alias_method for a class method?

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.

Ruby: Alias a method belonging to other class or module

One solution I found, thanks to Holger Just, is to use Forwardable:

require 'forwardable'
self.extend Forwardable
singleton_class.def_delegator "STDERR", "puts", "sp"

>> sp "a" "string"
astring

Although it is quite verbose and I'm not sure it would be better than just wrapping STDERR.puts into a new method.

When should I use an Alias Method? - Ruby

I think this is from an earlier question I responded to, where I proposed using alias_method, so I have a little bit of extra context into this to explain it's use in that context.

In your code snippet, you have a bit of code that reads attr_reader :thirsty that is basically a getter for an instance variable of the same name (@thirsty)

def thirsty
@thirsty
end

In the original code snippet, you had an assertion that was:

refute vampire.thirsty?

You also had code that simply returned true for thirsty? method, which failed your assertion.

There are at least two ways you could have modified your code so that the call to thirsty? worked and your assertion passed:

Create a method that calls the thirsty reader, or access the @thirsty instance variable itself:

def thirsty?
thirsty # or @thirsty
end

The other way is to use alias_method, which is functionally equivalent to the above. It aliases thirsty? to thirsty which is an attr_reader which reads from the @thirsty instance variable

Reference to the other answer I gave

You might be better off not using an attr_reader at all, instead just doing as Sergio noted in his comment:

class Vampire
def initialize(name)
@name = name
@thirsty = true
end

def thirsty?
@thirsty
end

def drink
@thirsty = false
end
end

Is there simpler (one-line) syntax to alias one class method?

Since Ruby 1.9 you can use the singleton_class method to access the singleton object of a class. This way you can also access the alias_method method. The method itself is private so you need to invoke it with send. Here is your one liner:

singleton_class.send(:alias_method, :generate, :new)

Keep in mind though, that alias will not work here.



Related Topics



Leave a reply



Submit