Objects are cool, but sometimes they're just a little too cool. Sometimes you would rather they behaved a little less like objects and a little more like regular data types. But there's a problem: objects are referents represented by references, and references aren't terribly useful except as references. You can't add references, or print them, or (usefully) apply many of Perl's built-in operators. The only thing you can do is dereference them. So you find yourself writing many explicit method invocations, like this:
print $object->as_string; $new_object = $subject->add($object);
Such explicit dereferencing is in general a good thing; you should never confuse your references with your referents, except when you want to confuse them. Now would be one of those times. If you design your class with overloading, you can pretend the references aren't there and simply say:
print $object; $new_object = $subject + $object;
When you overload one of Perl's built-in operators, you
define how it behaves when it's applied to objects of a particular
class. A number of standard Perl modules use overloading, such as
Math::BigInt
, which lets you create
Math::BigInt
objects that behave just like regular
integers but have no size limits. You can add them with
+
, divide them with /
, compare
them with <=>
, and print them with
print
.
Note that overloading is not the same as autoloading, which is loading a missing function or method on demand. Neither is it the same as overriding, which is one function or method masking another. Overloading hides nothing; it adds meaning to an operation that would have been nonsense on a mere reference.
The use overload
pragma implements
operator overloading. You provide it with a key/value list of
operators and their associated behaviors:
package MyClass; use overload '+' => &myadd, # coderef '<' => "less_than", # named method 'abs' => sub { return @_ }; # anonymous subroutine
Now when you try to add two MyClass
objects,
the myadd
subroutine will be called to create the
result.
When you try to compare two MyClass
objects
with the <
operator, Perl notices that the
behavior is specified as a string and interprets the string as a
method name and not simply as a subroutine name. In the example above,
the less_than
method might be supplied by the
MyClass
package itself or inherited from a base
class of MyClass
, but the myadd
subroutine must be supplied by the current package. The anonymous
subroutine for abs
supplies itself even more
directly. However these routines are supplied, we'll call them
handlers.
For unary operators (those taking only one operand,
like abs
), the handler specified for the class is
invoked whenever the operator is applied to an object of that
class.
For binary operators like +
or
<
, the handler is invoked whenever the first
operand is an object of the class or when the
second operand is an object of the class and the first operand has no
overloading behavior. That's so you can say either:
$object + 6
or:
6 + $object
without having to worry about the order of operands. (In the second case, the operands will be swapped when passed to the handler). If our expression was:
$animal + $vegetable
and $animal
and $vegetable
were objects of different classes, both of which used overloading,
then the overloading behavior of $animal
would be
triggered. (We'll hope the animal likes vegetables.)
There is only one trinary (ternary) operator in Perl,
?
:, and you can't overload it. Fortunately.