Browsing through the MRI codebase, I find that some aliased methods are defined as aliases, but other times not.
For example, TrueClass#inspect is an alias to its #to_s (source):
rb_define_alias(rb_cTrueClass, "inspect", "to_s");
... but Object#is_a? is not an alias for kind_of?, instead, they define two separate methods with the same implementing function (source):
rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
This distinction is observable from "userspace" Ruby, too:
# Aliased methods have a different `original_name`:
true.method(:inspect).original_name # => :to_s
# "Duplicated" methods don't:
true.method(:is_a?).original_name # => :is_a?
true.method(:kind_of?).original_name # => :kind_of?
Is there a pattern to when aliases used, vs. when they're not? Does it make a difference?
This is by no means an authoritative answer to the question, nor does it truly answer the questions posed; however, it does provide some distinguishing characteristics between the options provided and was far too verbose to meet the format of a reasonable comment.
Questions
Is there a pattern to when aliases used, vs. when they're not?
I can't say. Possibly only Matz or a part of the core team could answer this for you.
Does it make a difference?
It could as shown here.
There is a notable difference between aliasing and defining multiple methods with the same implementation, when it comes to redefinition of the function1 (or method) referenced.
Aliasing
rb_define_alias(rb_cTrueClass, "inspect", "to_s");
rb_define_alias actually clones the function definition when creating the alias using rb_method_entry_clone.
Since the function is actually cloned (and not just referenced) any subsequent change to rb_mod_to_s (the function to_s refers to) or redefinition of the actual to_s method within Ruby code will not impact the definition of inspect, which will still represent the original function.
This is how alias and alias_method2 in higher level ruby work as well, using essentially the same function calls as rb_define_alias
Separate Method Definitions with the same implementation
rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
rb_define_method simply creates a method reference to the underlying function, so should the implementation of rb_obj_is_kind_of change, such change would impact both kind_of? and is_a? since they are directly referencing that function.
Higher Level Example
We can see similar behavior within Ruby:
class Foo
# Aliasing
def to_s = 'Foo'
alias inspect to_s
# or even this which more visibly represents the concept of cloning a method
define_method(:other_inspect, instance_method(:to_s))
# Separate Method Definitions with the same implementation
def _kind_of? = true
define_method(:is_a?) {_kind_of?}
define_method(:kind_of?) {_kind_of?}
end
Foo.new.to_s #=> 'Foo'
Foo.new.inspect #=> 'Foo'
Foo.new.other_inspect #=> 'Foo'
Foo.new.is_a? #=> true
Foo.new.kind_of? #=> true
class Foo
def to_s = 'Bar'
def _kind_of? =false
end
Foo.new.to_s #=> 'Bar'
Foo.new.inspect #=> 'Foo'
Foo.new.other_inspect #=> 'Foo'
Foo.new.is_a? #=> false
Foo.new.kind_of? #=> false
Also note even though the definition of to_s has changed the "original name" for both inspect and other_inspect will still return to_s.
(2) There are distinct differences between alias and alias_method beyond the scope of this question
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With