Main Content

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$