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:
Ruby
class Car
attr_accessor :name , :color
def initialize(name, color)
@name = name
@color = color
end
def +(obj)
return Car. new ("
"
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
class Car
attr_accessor :name , :color
def initialize(name, color)
@name = name
@color = color
end
def /(obj)
return Car. new ("
"
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
class Comparable_operator
include Comparable
attr_accessor :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
class Comparable_operator
include Comparable
attr_accessor :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
class Tester
attr_accessor :num
def initialize(num)
@num = num
end
def +(obj)
return @num +obj
end
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
class Tester
attr_accessor :num
def initialize(num)
@num = num
end
def +(obj)
return self .num+obj.num
end
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
class Array_Operators
attr_accessor :arr
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.
Last Updated :
17 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...