Changing what operators do on objects - a comparison across different programming languages
Archive - Originally posted on "The Horse's Mouth" - 2014-12-26 16:31:54 - Graham Ellis
In Object Oriented languages, you used named pieces of code known as methods to perform an operation on a variable - for example you might write weeklist.extend(weekend)
to take a list of (something) for a week and add a list relating to weekend onto the end of it.
Sometimes, the method you use might be considered to be an "addition" and in some languages you can actually (re)define operators such as "+" so that you can write things like week = weeklist + weekend
if you want to.
This facility is know as "operator overloading" and, given the right circumstances and a language that supports it, it can be very useful indeed. I'm going to take a look at each of the languages I teach, and where operator overloading is available I'll show you how to call it. I have also overloaded the conversion of objects into strings where I can, so that you can simple write something like print (object_var_name)
and you'll get a good representation of the object, not just a type / memory addrss / error message.
C and C++
In C++, you can overload the "+" operator by defining a function called opertor+ in you class. It doesn't work too well with pointers, because the C++ compile needs to be able to use + to do address (pointer) arithmetic.
Here's an example of how our test program ran:
WomanWithCat:ruby grahamellis$ ./overload_add
Service every 10 uses for Beans
Service every 7 uses for Water
Service every 4.11765 uses for Beans; Water
WomanWithCat:ruby grahamellis$
And here's the calling code:
int main () {
Mtbs *beans = new Mtbs(10.0,"Beans");
Mtbs *water = new Mtbs(7.0,"Water");
Mtbs fill = *beans + *water;
cout << *beans << endl;
cout << *water << endl;
cout << fill << endl;
}
The complete example, including the definition of the class and the add method within it, may be found [here].
Perl
In Perl, the use overload pragma lets you reassign an operator (and indeed " to " is an operator) to a named function. Once you've done that you can write things like
$beans = new mtbs(10,"Beans");
$water = new mtbs(7,"Water");
$fill = $beans + $water;
print $beans;
print $water;
print $fill;
and get results like
WomanWithCat:ruby grahamellis$ perl overload_add.pl
Service Beans every 10.00 cups
Service Water every 7.00 cups
Service Beans and Water every 4.12 cups
WomanWithCat:ruby grahamellis$
The complete example, together with the add and "tostring" methods used to redefine addition, may be found [here].
Python
In Python, everything's an object and so it's perhaps the most natural language in which to override operators - in fact operators are no more than "syntactic icing" around the language's object syntax in the first place!
Source code calling up the methods will look like:
if __name__ == "__main__":
beans = mtbs(10,"Beans")
water = mtbs(7,"Water")
fill = beans + water
print beans
print water
print fill
Which runs as follows:
WomanWithCat:ruby grahamellis$ python overload_add.py
Beans every 10.00
Water every 7.00
Beans and Water every 4.12
WomanWithCat:ruby grahamellis$
Full source code for the complete example, including definition of the __add__ method, may be found [here].
With Python, note that as well as the __add__ method to overload addition based on the obejct to the left of the + sign, you can also provide a __radd__ method to overload the object to the right, and an __iadd__ method to overload the += operator.
Ruby
You define addition on your own objects in Ruby by defining a method called "+" in the class you want to be able to add - beautifuly simple. Here's the calling code:
if __FILE__ == %body%
beans = Mtbs.new(10,"Beans")
water = Mtbs.new(7,"Water")
fill = beans + water
print beans
print water
print fill
end
And the result from running that code:
WomanWithCat:ruby grahamellis$ ruby overload_add.rb
Every 10.00 service Beans
Every 7.00 service Water
Every 4.12 service Beans or Water
You have new mail in /var/mail/grahamellis
WomanWithCat:ruby grahamellis$
The complete code, including the definition of the class, may be found [here].
PHP and Java
PHP and Java do not support operator overloading, partly on a matter of principle and partly because the folks who look after the languages don't see a need for it. They're probably correct in that assessment, as languages do differ from one another and the very obvious gains that operator overriding has in language such as Python and Ruby are by no means obviously advantages in either Java or PHP.
Lua
In lua, you can define the __add method in a metatable, and associate that metatable with any other table you wish, which will result in you changing the character of what the + operator does when applied to that table. So you can write code like
if __FILE__ == %body%
beans = Mtbs.new(10,"Beans")
water = Mtbs.new(7,"Water")
fill = beans + water
print beans
print water
print fill
end
which produced results like
WomanWithCat:ruby grahamellis$ lua overload_add.lua
Attention needed for Beans every 10.00 cups
Attention needed for Water every 7.00 cups
Attention needed for Beans plus Water every 4.12 cups
WomanWithCat:ruby grahamellis$
The complete example, including setting up the tables with Mtbs characeristics, may be found [here].
Tcl
Alone amongst the languages that we teach, Tcl does not have natural objects nor method overrides, although there is an object capability within IncrTcl.
Operator overload is a bit specialist on many of our courses - we'll cover it on an as-requeired basis, but these examples are always available to get your started. Our course descriptions / public schedule is [here] .. please ask if you want private training on site, or coverage of specific intermediate or advanced topics - we can often help!
WomanWithCat:ruby grahamellis$