Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MRI: Why are some methods implemented as aliases, but others duplicated?

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?

like image 640
Alexander Avatar asked Oct 22 '25 10:10

Alexander


1 Answers

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.

(1) The term function was used in this post because the question is specifically referring to the underlying C implementation. Ruby as a language does not have functions.

(2) There are distinct differences between alias and alias_method beyond the scope of this question

like image 172
engineersmnky Avatar answered Oct 23 '25 23:10

engineersmnky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!