Operator Overloading in Ruby (original) (raw)
Last Updated : 17 May, 2022
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.