Overloading¶
We can define a become_older
method that accepts a number indicating the years to grow:
classPersongetter:agedefinitialize(@name:String,@age:Int=0)enddefbecome_older@age+=1enddefbecome_older(years)@age+=yearsendendjohn=Person.new"John"john.age# => 0john.become_olderjohn.age# => 1john.become_older5john.age# => 6
That is, you can have different methods with the same name and different number of parameters and they will be considered as separate methods. This is called method overloading.
Methods overload by several criteria:
- The number of parameters
- The type restrictions applied to parameters
- The names of required named parameters
- Whether the method accepts a block or not
For example, we can define four different become_older
methods:
classPerson@age=0# Increases age by onedefbecome_older@age+=1end# Increases age by the given number of yearsdefbecome_older(years:Int32)@age+=yearsend# Increases age by the given number of years, as a Stringdefbecome_older(years:String)@age+=years.to_iend# Yields the current age of this person and increases# its age by the value returned by the blockdefbecome_older(&)@age+=yield@ageendendperson=Person.new"John"person.become_olderperson.age# => 1person.become_older5person.age# => 6person.become_older"12"person.age# => 18person.become_olderdo|current_age|current_age<20?10:30endperson.age# => 28
Note that in the case of the method that yields, the compiler figured this out because there's a yield
expression. To make this more explicit, you can add a dummy &block
parameter at the end:
classPerson@age=0defbecome_older(&block)@age+=yield@ageendend
In generated documentation the dummy &block
method will always appear, regardless of you writing it or not.
Given the same number of parameters, the compiler will try to sort them by leaving the less restrictive ones to the end:
classPerson@age=0# First, this method is defineddefbecome_older(age)@age+=ageend# Since "String" is more restrictive than no restriction# at all, the compiler puts this method before the previous# one when considering which overload matches.defbecome_older(age:String)@age+=age.to_iendendperson=Person.new"John"# Invokes the first definitionperson.become_older20# Invokes the second definitionperson.become_older"12"
However, the compiler cannot always figure out the order because there isn't always a total ordering, so it's always better to put less restrictive methods at the end.