Method Overloading In Ruby

01 Apr, 2020
What is method overloading?Method overloading is a feature that allows a class to have more than one method with same name but different method signature ie. different number of arguments, order of arguments and different types of parameters. Return type is not included in method signature, thus overloaded methods can have different return type. Method overloading is an example of static binding or compile time polymorphism.
Ruby does not support method overloadingMethod overloading is a feature of statically typed language in which binding of methods takes place during compile time. But Ruby being a dynamically typed language, it does not support static binding at all. Also it is difficult to determine which method will be invoked in case of dynamic argument-based dispatch in a language with optional arguments and variable-length argument lists. In addition, the implementing language of Ruby is C which itself does not support method overloading. The most recent version of the method is considered while ignoring the previously defined versions of the method.Example below shows Ruby does not support usual approach of method overloadingExample #1:
class Test    def self.sum(a,b)        puts(a+b)    end    def self.sum(a,b,c)        puts(a+b+c)    end      endTest.sum(1,2)
Output:
main.rb:13:in `sum': wrong number of arguments (2 for 3) (ArgumentError)                                                      
        from main.rb:18:in `'           
In Ruby, when a second method is defined with the same name it completely overrides the previously existing method. The previous method is no longer accessible and hence throws error when we try to access it.
Example #2:
class Test    def self.sum(a,b)        puts(a+b)    end    def self.sum(a,b,c)        puts(a+b+c)    end      endTest.sum(1,2,7)
Output:
10
The second method overwrites the previous method and hence it works absolutely fine when we call the method with three arguments. Implementing method overloading in RubyA possible approach to implement overloading in Ruby can be by varying the number of arguments of the method. However, overloading methods using different types of arguments is possible but it becomes really difficult to keep a trace of the code.Both the approaches are demonstrated below:Method overloading by varying the number of arguments
Using Class MethodsExample :class Test    def self.display(*args)        case args.size            when 1                puts "1: Hello #{args[0]}"            when 2                puts "2: Hello #{args[0]} #{args[1]}"            when 3                puts "3: Hello #{args[0]} #{args[1]} Welcome to #{args[2]} language."        end    endend puts "Overloading using Class Method"Test.display"Geeks!!" Test.display"Geeks!!", "Hope you doing great."Test.display"Geeks!!", "Hope you doing great.", "Ruby"OutputOverloading using Class Method
1: Hello Geeks!!
2: Hello Geeks!! Hope you doing great.
3: Hello Geeks!! Hope you doing great. Welcome to Ruby language.
The display() method is a class method. In Ruby, a class method provides functionality to the class itself. Hence we call the method directly using the class name followed by the dot operator and method name. Class methods are public by default.
class Test    def self.display(*args)        case args.size            when 1                puts "1: Hello #{args[0]}"            when 2                puts "2: Hello #{args[0]} #{args[1]}"            when 3                puts "3: Hello #{args[0]} #{args[1]} Welcome to #{args[2]} language."        end    endend puts "Overloading using Class Method"Test.display"Geeks!!" Test.display"Geeks!!", "Hope you doing great."Test.display"Geeks!!", "Hope you doing great.", "Ruby"
Output
Overloading using Class Method
1: Hello Geeks!!
2: Hello Geeks!! Hope you doing great.
3: Hello Geeks!! Hope you doing great. Welcome to Ruby language.

The display() method is a class method. In Ruby, a class method provides functionality to the class itself. Hence we call the method directly using the class name followed by the dot operator and method name. Class methods are public by default.
 
Using Instance MethodsExample :class Test    def display(*args)        case args.size            when 1                puts "1: Hello #{args[0]}"            when 2                puts "2: Hello #{args[0]} #{args[1]}"            when 3                puts "3: Hello #{args[0]} #{args[1]} Welcome to #{args[2]} language."        end    endend   ob1 = Test.newob2 = Test.newob3 = Test.newputs "Overloading using Instance Method"  ob1.display"Geeks!!" ob2.display"Geeks!!", "Hope you doing great."ob3.display"Geeks!!", "Hope you doing great.", "Ruby"OutputOverloading using Instance Method
1: Hello Geeks!!
2: Hello Geeks!! Hope you doing great.
3: Hello Geeks!! Hope you doing great. Welcome to Ruby language.
The instance method display() provides functionality to the instances of the class. We need to create instances of the class to call the instance method of the class. An instance method cannot be called directly using the class name.
class Test    def display(*args)        case args.size            when 1                puts "1: Hello #{args[0]}"            when 2                puts "2: Hello #{args[0]} #{args[1]}"            when 3                puts "3: Hello #{args[0]} #{args[1]} Welcome to #{args[2]} language."        end    endend   ob1 = Test.newob2 = Test.newob3 = Test.newputs "Overloading using Instance Method"  ob1.display"Geeks!!" ob2.display"Geeks!!", "Hope you doing great."ob3.display"Geeks!!", "Hope you doing great.", "Ruby"
Output
Overloading using Instance Method
1: Hello Geeks!!
2: Hello Geeks!! Hope you doing great.
3: Hello Geeks!! Hope you doing great. Welcome to Ruby language.

The instance method display() provides functionality to the instances of the class. We need to create instances of the class to call the instance method of the class. An instance method cannot be called directly using the class name.
 
Method overloading by varying the number of arguments and types of argumentsExample :def sum(*args)          case args.size        when 2            if args[0].is_a?(Integer) && args[1].is_a?(Integer)                puts "Int addition: #{args[0].to_i + args[1].to_i}"                      elsif args[0].is_a?(Integer) && args[1].is_a?(Float)                puts "Int and Float addition: #{args[0].to_i + args[1].to_f}"            elsif args[0].is_a?(Float) && args[1].is_a?(Integer)                puts "Float and Int addition: #{args[0].to_f + args[1].to_i}"            end                      when 3            if args[0].is_a?(Integer) && args[1].is_a?(Integer) && args[2].is_a?(Integer)                puts "Int addition: #{args[0].to_i + args[1].to_i + args[2].to_i}"                      elsif args[0].is_a?(Integer) && args[1].is_a?(Float) && args[2].is_a?(Integer)                puts "Int, Float and Int addition: #{args[0].to_i + args[1].to_f + args[2].to_i}"            elsif args[0].is_a?(Float) && args[1].is_a?(Integer) && args[2].is_a?(Float)                puts "Float, Int, Float addition: #{args[0].to_f + args[1].to_i + args[2].to_f}"            end                  endend  sum 5, 7sum 2.0, 6sum 4, 5.2sum 2, 3, 5sum 4.5, 5, 3.5sum 1, 2.5, 3OutputInt addition: 12
Float and Int addition: 8.0
Int and Float addition: 9.2
Int addition: 10
Float, Int, Float addition: 13.0
Int, Float and Int addition: 6.5
As the number of argument increases the code becomes complex. However we can keep increasing the number of cases to handle varying number of arguments.
def sum(*args)          case args.size        when 2            if args[0].is_a?(Integer) && args[1].is_a?(Integer)                puts "Int addition: #{args[0].to_i + args[1].to_i}"                      elsif args[0].is_a?(Integer) && args[1].is_a?(Float)                puts "Int and Float addition: #{args[0].to_i + args[1].to_f}"            elsif args[0].is_a?(Float) && args[1].is_a?(Integer)                puts "Float and Int addition: #{args[0].to_f + args[1].to_i}"            end                      when 3            if args[0].is_a?(Integer) && args[1].is_a?(Integer) && args[2].is_a?(Integer)                puts "Int addition: #{args[0].to_i + args[1].to_i + args[2].to_i}"                      elsif args[0].is_a?(Integer) && args[1].is_a?(Float) && args[2].is_a?(Integer)                puts "Int, Float and Int addition: #{args[0].to_i + args[1].to_f + args[2].to_i}"            elsif args[0].is_a?(Float) && args[1].is_a?(Integer) && args[2].is_a?(Float)                puts "Float, Int, Float addition: #{args[0].to_f + args[1].to_i + args[2].to_f}"            end                  endend  sum 5, 7sum 2.0, 6sum 4, 5.2sum 2, 3, 5sum 4.5, 5, 3.5sum 1, 2.5, 3
Output
Int addition: 12
Float and Int addition: 8.0
Int and Float addition: 9.2
Int addition: 10
Float, Int, Float addition: 13.0
Int, Float and Int addition: 6.5

As the number of argument increases the code becomes complex. However we can keep increasing the number of cases to handle varying number of arguments.
Picked
Ruby-Methods
Ruby
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Make a Custom Array of Hashes in Ruby?
Ruby | Array count() operation
Ruby | Array slice() function
Include v/s Extend in Ruby
Global Variable in Ruby
Ruby | Array select() function
Ruby | Enumerator each_with_index function
Ruby | Case Statement
Ruby | unless Statement and unless Modifier
Ruby | Hash delete() function