Operator Overloading in Ruby

Ruby permits operator overloading, allowing one to define how an operator shall be used in a particular program. For example a ‘+’ operator can be define in such a way to perform subtraction instead addition and vice versa. The operators that can be overloaded are +, -, /, *, **, %, etc and some operators that can not be overloaded are &, &&, |, ||, (), {}, ~, etc.

Operator functions are same as normal functions. The only differences are, name of an operator function is always symbol of operator followed operator object. Operator functions are called when the corresponding operator is used. Operator overloading is not commutative that means that 3 + a is not same as a + 3. When someone tries to run 3 + a, it will fail.
Below is the example of Ruby Operator overloading.
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Car
    attr_accessor:name, :color
  
    # Initialize the name and color
    def initialize(name, color)
        @name = name
        @color = color
    end
    def +(obj)
        return Car.new("#{self.name}#{obj.name}"
                  "#{self.color}#{obj.color}")
    end
end
a = Car.new("Mercedes", "Red")
b = Car.new("Audi", "Silver")
puts (a+b).inspect

chevron_right


Output :



#<Car:0x000000020a0620 @name="MercedesAudi", @color="RedSilver">

As we can see that the ‘+’ operator has been overloaded and thus it gives back the two concatenated string output of name and color.

This is another example with the same code but this time instead of ‘+’ operator we have overloaded the ‘/’ operator.
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Car
    attr_accessor:name, :color
  
    # Initialize the name and color
    def initialize(name, color)
        @name = name
        @color = color
    end
    def /(obj)
        return Car.new("#{self.name}#{obj.name}",
                     "#{self.color}#{obj.color}")
    end
end
a = Car.new("Mercedes", "Red")
b = Car.new("Audi", "Silver")
puts (a/b).inspect

chevron_right


Output :

#<Car:0x000000020a0620 @name="MercedesAudi", @color="RedSilver">

We can see that the output is same because in the above case we have overloaded ‘/’ operator to perform concatenation, thus we can overload any operator irrespective of its usual usage.

In the below example we will try to overload comparable operators:
(Note: In this we will use a ruby module Comparable.In Ruby, the Comparable module is used by the class whose objects may be ordered.If the receiver is less than another object, then it returns -1, if the receiver is equal to another object, then it returns 0. If the receiver is greater than another object, then it returns 1.)
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Comparable_operator
    include Comparable
    attr_accessor:name
  
    # Initialize the name
    def initialize(name)
        @name=name
    end
    def <=>(obj)
        return self.name<=>obj.name
    end
end
a = Comparable_operator.new("Geeks for Geeks")
b = Comparable_operator.new("Operator Overloading")
puts a<=>b

chevron_right


Output :

false

In above example, the output is false because the ASCII code ‘G'(ASCII=71) is less than ‘O'(ASCII=79) and thus after checking whether 71 is greater than 79, its gives an output of false. (Note: We can also use =, ==, operators to check)

This is another example with the same code but this time we will compare the actual strings:
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Comparable_operator
    include Comparable
    attr_accessor:name
  
    # Initialize the name
    def initialize(name)
        @name=name
    end
    def <=>(obj)
        return self.name<=>obj.name
    end
end
puts "Geeks for Geeks"<=>"Operator Overloading"

chevron_right


Output :

-1

In above example, the output is -1 because because the ASCII code ‘G’ is less than ‘O’


In the below example we will try to overload an operator by an integer:
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
# By an Integer
class Tester
    attr_accessor:num
  
    # Initialize the num
    def initialize(num)
        @num = num
    end
  
    # Define + to do addition
    def +(obj)
        return @num+obj
    end
  
    # Define * to do Multiplication
    def *(obj)
        return @num*obj
    end
    def **(obj)
        return @num**obj
    end
end
a=Tester.new(5)
puts a + 3
puts a * 3
puts a ** 3

chevron_right


Output :

8
15
125

If we had passed an object for an integer, we would have used keywords to identify the variables.
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Tester
    attr_accessor:num
  
    # Initialize the num
    def initialize(num)
        @num = num
    end
  
    # Define + to do addition
    def +(obj)
        return self.num+obj.num
    end
  
    # Define * to do Multiplication
    def *(obj)
        return self.num*obj.num
    end
    def **(obj)
        return self.num**obj.num
    end
end
a = Tester.new(5)
b = Tester.new(4)
puts a + b
puts a * b
puts a ** b

chevron_right


Output :

9
20
625

(Note: Operator Overloading is not a commutative operation, i.e., if we have used 3 + a in instead of a + 3 we would have got an error like this:
source_file.rb:17:in `+’: Tester can’t be coerced into Fixnum (TypeError)
from source_file.rb:17:in `’)

In the below example we will try to overload element reference operators:
(Note: ‘+=’ operator has to be defined via the + operator, i.e., we just have to define the ‘+’ operator and the compiler automatically uses it in the sense of ‘+=’ and ‘<<‘ operator appends an element in the end of the array)
Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

# Ruby program of Operator Overloading
class Array_Operators
    attr_accessor:arr
  
    # Initialize the array
    def initialize(*arr)
        @arr = arr
    end
    def [](x)
        @arr[x]
    end
    def [] = (x, value)
        @arr[x] = value
    end
    def <<(x)
        @arr << x
        return ('#{@arr}')
    end
end
a = Array_Operators.new(0, 3, 9, 27, 81)
puts a[4]
a[5] = 51
puts a[5]
puts a << 41
puts a[6]

chevron_right


Output :

81
51
[0, 3, 9, 27, 81, 51, 41]
41

We can see that we the operators has worked as defined and all the elements of the array is shown. Thus we can easily overload most of the operator in Ruby to suit our needs.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.