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
Safe Navigation Operator (&.) for Nil
Ruby: Split String at Character, Counting from the Right Side
Ruby Regex Error: Incompatible Encoding Regexp Match (Ascii-8Bit Regexp with Utf-8 String)
Setter Method (Assignment) with Multiple Arguments
Sinatra Clears Session on Post
Invalid Gemspec -Illformed Requirement ["#<Yaml::Syck::Defaultkey:0Xb5F9C990> 3.2.0"]
Problem with Quantifiers and Look-Behind
Why Is Gets Throwing an Error When Arguments Are Passed to My Ruby Script
How to Deal with Memory Leaks in Rmagick in Ruby
Ruby: Intersection Between Two Ranges
Heroku App Crash H10 - Bash: Bin/Rails: No Such File or Directory
Heroku: Gemfile.Lock Is Required Issue
Ruby Gem Dependencies on Offline Server
Converting a Hexadecimal Digest to Base64 in Ruby
Is There a Cucumber Hook to Run Before and After Each Feature
How to Validate Xhtml with Nokogiri
Rvm Does Not Install Ruby 1.9.2 on Snow Leopard: 'Error Running 'Make '