Perl 5 is not a pervasively object oriented language. Its core data types (scalars, arrays, and hashes) are not objects with overloadable methods, but you can control the behavior of your own classes and objects, especially when they undergo coercion or contextual evaluation. This is overloading.
Overloading can be subtle but powerful. An interesting example is overloading how an object behaves in boolean context, especially if you use something like the Null Object pattern (http://www.c2.com/cgi/wiki?NullObject). In boolean context, an object will evaluate to a true value, unless you overload boolification.
You can overload what the object does for almost every operation or coercion: stringification, numification, boolification, iteration, invocation, array access, hash access, arithmetic operations, comparison operations, smart match, bitwise operations, and even assignment. Stringification, numification, and boolification are the most important and most common.
The overload
pragma allows you to associate a function with an operation you can overload by passing argument pairs, where the key names the type of overload and the value is a function reference to call for that operation. A Null
class which overloads boolean evaluation so that it always evaluates to a false value might resemble:
It's easy to add a stringification:
Overriding numification is more complex, because arithmetic operators tend to be binary ops (arity). Given two operands both with overloaded methods for addition, which takes precedence? The answer needs to be consistent, easy to explain, and understandable by people who haven't read the source code of the implementation.
perldoc overload
attempts to explain this in the sections labeled Calling Conventions for Binary Operations and MAGIC AUTOGENERATION, but the easiest solution is to overload numification (keyed by '0+'
) and tell overload
to use the provided overloads as fallbacks where possible:
Setting fallback
to a true value lets Perl use any other defined overloads to compose the requested operation when possible. If that's not possible, Perl will act as if there were no overloads in effect. This is often what you want.
Without fallback
, Perl will only use the specific overloadings you have provided. If someone tries to perform an operation you have not overloaded, Perl will throw an exception.
Subclasses inherit overloadings from their ancestors. They may override this behavior in one of two ways. If the parent class uses overloading as shown, with function references provided directly, a child class must override the parent's overloaded behavior by using overload
directly.
Parent classes can allow their descendants more flexibility by specifying the name of a method to call to implement the overloading, rather than hard-coding a function reference:
In this case, any child classes can perform these overloaded operations differently by overriding the appropriate named methods.
Overloading may seem like a tempting tool to use to produce symbolic shortcuts for new operations, but it's rare in Perl 5 for a good reason. The IO::All
CPAN distribution pushes this idea to its limit to produce clever ideas for concise and composable code. Yet for every brilliant API refined through the appropriate use of overloading, a dozen more messes congeal. Sometimes the best code eschews cleverness in favor of simplicity.
Overriding addition, multiplication, and even concatenation on a Matrix
class makes sense, only because the existing notation for those operations is pervasive. A new problem domain without that established notation is a poor candidate for overloading, as is a problem domain where you have to squint to make Perl's existing operators match a different notation.
Damian Conway's Perl Best Practices suggests one other use for overloading: to prevent the accidental abuse of objects. For example, overloading numification to croak()
for objects which have no reasonable single numeric representation can help you find and fix real bugs.
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 11:
-
Deleting unknown formatting code U<>