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
# 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.
Please Login to comment...