Open In App

Operator Overloading in Ruby

Last Updated : 17 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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: 

Ruby




# 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


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: 

Ruby




# 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


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: 

Ruby




# 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


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: 

Ruby




# 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"


Output :

-1

In above example, the output is -1 because  the ASCII code ‘G’ is less than ‘O’ In the below example we will try to overload an operator by an integer: 

Example: 

Ruby




# 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


Output :

8
15
125

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

Example: 

Ruby




# 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


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: 

Ruby




# 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]


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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads