Add the following code to your project's shard.yml under:
dependencies
to use in production
- OR -
development_dependencies
to use in development
Crystal does not natively support the creation of method aliases. This is by design, and the general philosophy of the language is that any given method should only be called by a single name.
However, there are times when one might want to create method aliases. It is certainly possible to hand-write code to do this, but this shard provides a single-line way of aliasing a method. It works for both instance methods and for class methods.
Add the dependency to your shard.yml
:
dependencies:
alias_method:
github: wyhaines/alias_method.cr
Run shards install
See the complete documentation for full information on this shard and how to use it.
require "alias_method"
class MyClass
def self.add(x, y)
x + y
end
def with(arg)
yield arg
end
def [](val)
val ** 3
end
def chain(ary)
ary << "a"
end
alias_method "self.suma", "self.add" # Class method alias
alias_method suma, MyClass.add # Instance method alias to a class method
alias_method con, :with, 1 # Alias to a method that yields
alias_method cube, :[] # Alias to a method name that has punctuation
alias_method nada, nothing # Alias to a method that doesn't exist (no error)
alias_method chain_a, chain # Create a chain of aliases
def chain(ary)
chain_a(ary) << "b"
end
alias_method chain_b, chain
def chain(ary)
chain_b(ary) << "c"
end
end
foo = MyClass.new
puts "Call the MyClass.add class method via the class method alias, MyClass.suma: #{MyClass.suma(123, 456)}"
puts "Call the MyClass.add class method via the instance method alias, MyClass#suma: #{foo.suma(456, 789)}"
puts "Call an alias to a method that takes a block: #{foo.con(7) {|x| x ** x}}"
puts "Call a method that forms a chain of aliased methods: #{foo.chain([] of String).inspect}"
The shard also implements a remove_method
macro that can be used to (sort of) remove methods. Crystal does not actually provide any ability to truly undefine a method, so this macro redefines the removed method to throw a NoMethodError
exception.
class MyClass
def self.add(x, y)
x + y
end
def with(arg)
yield arg
end
# Spanish translations of the method names:
alias_method "suma", "self.add"
alias_method "con", "with"
# Remove the English versions.
remove_method "with"
remove_method "self.add"
end
Aliasing methods has no impact on performance, when compiling in release mode (in development mode, they are approximately 1/2 as fast as unaliased methods).
--------------------------------
bare, aliased, alias 968.52M ( 1.03ns) (± 2.71%) 0.0B/op fastest
bare, aliased, original 965.20M ( 1.04ns) (± 2.67%) 0.0B/op 1.00× slower
bare, unaliased 965.87M ( 1.04ns) (± 2.65%) 0.0B/op 1.00× slower
--------------------------------
with arguments, aliased, alias 970.17M ( 1.03ns) (± 2.43%) 0.0B/op fastest
with arguments, aliased, original 962.70M ( 1.04ns) (± 2.55%) 0.0B/op 1.01× slower
with arguments, unaliased 964.02M ( 1.04ns) (± 2.44%) 0.0B/op 1.01× slower
--------------------------------
with block, aliased, alias 966.57M ( 1.03ns) (± 2.33%) 0.0B/op fastest
with block, aliased, original 961.09M ( 1.04ns) (± 4.18%) 0.0B/op 1.01× slower
with block, unaliased 966.30M ( 1.03ns) (± 2.40%) 0.0B/op 1.00× slower
--------------------------------
with yield, aliased, alias 968.25M ( 1.03ns) (± 2.17%) 0.0B/op fastest
with yield, aliased, original 966.45M ( 1.03ns) (± 2.49%) 0.0B/op 1.00× slower
with yield, unaliased 966.61M ( 1.03ns) (± 2.49%) 0.0B/op 1.00× slower
--------------------------------
class method, aliased, alias 968.68M ( 1.03ns) (± 2.83%) 0.0B/op fastest
class method, aliased, original 966.72M ( 1.03ns) (± 2.63%) 0.0B/op 1.00× slower
class method, unaliased 967.43M ( 1.03ns) (± 2.27%) 0.0B/op 1.00× slower
--------------------------------
One interesting thing to note is that there seems to be a very slight bias in benchmark outcomes, based on the order of the code being benchmarked. In general, the first block tends to benchmark very slightly faster than the last, which means that if the order of each of the items in the benchmark is reversed, so that unaliased is first, and the aliased method is last, the above results would likely lean towards unaliased first. However, the effect is very slight. There is no appreciable difference in performance, in release mode code, between an aliased method and an unaliased method.
If you wish to contribute to this shard, please fork the repository, and work from a branch within your own fork. When your work is complete (and has appropriate specs), submit a PR. Thank you!
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)