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.
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...
Alias a method to a single object
Singleton methods are contained in that object's singleton class:
class Object
def define_singleton_alias(new_name, old_name)
singleton_class.class_eval do
alias_method new_name, old_name
end
end
end
rob = 'Rob'
bob = 'Bob'
bob.define_singleton_alias :add_cuteness, :+
bob.add_cuteness 'by' # => "Bobby"
rob.add_cuteness 'by' # => NoMethodError
Object#define_singleton_method
basically does something like this:
def define_singleton_method(name, &block)
singleton_class.class_eval do
define_method name, &block
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.
How can I dynamically define an alias method for a class method?
So just learned that this will do the trick:
module Calculator
def memoize
define_singleton_method(name, method(name))
end
end
Then when Calculator gets included in Product it will define the singleton method as I needed. I still don't know why alias_method needs to only work on instance methods.. and I don't know why class_eval or instance_eval didn't solve the problem.. but at least I have a solution..
How to include a module in a model class with alias?
Modules are not classes and thus cannot use classical hierarchical inheritance. However a module can include other modules - which means you can use paralell inheritance.
module Name
extend ActiveSupport::Concern
included do
field :name, type: String
end
def greeting(name)
p "hello #{name}!"
end
end
module Nickname
extend ActiveSupport::Concern
include Name
included do
field :nickname, type: String
end
# if you named this method greeting it would
# overwrite the implementation from the Name module
def friendly_greeting(name)
p "hello #{name}! You can call me #{nickname}"
end
end
class Foo
include Name
end
class Bar
include Nickname
end
Foo.new.name # nil
Foo.new.nickname # NoMethodError
Foo.fields.keys # ['_id', 'name']
Bar.fields.keys # ['_id', 'name', 'nickname']
Foo.new(name: 'Max').greeting # "hello Max!"
Foo.new(name: 'Max').friendly_greeting # NoMethodError
bar = Bar.new(name: 'Richard', nickname: 'Dick')
bar.greeting # "hello Richard!"
bar.friendly_greeting # "hello Richard! You can call me Dick"
alias for chain methods in rails
class User < ApplicationRecord
belongs_to :mother, class_name: "User", optional: true
belongs_to :father, class_name: "User", optional: true
has_one :grandfather, through: :father, source: :father
has_one :grandmother, through: :father, source: :mother
end
Related Topics
<Rubygems> How to Change Gem Environment Settings
Star Rating in Ajax with Ruby on Rails
Get Server File Path with Paperclip
Use Global or Constant Variable in Ruby/Rails
Using Named Captures with Regex Match in Ruby's Case...When
How to Assign Multiple Values to a Hash Key
Rails Force Models to Eager Load
Synchronized Method for Concurrency in Ruby
Heroku: No Rakefile Found (But Works Locally)
How to Highlight Fields on Rails Validation Errors
How to Sort by Multiple Conditions with Different Orders
No Such File to Load Bundler Error for Rails 3
Testing After_Commit with Rspec and Mocking
Failing to Install Nokogiri Gem
How to Get the Current Route in Rails
Restful File Uploads with Carrierwave