home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

Book Home Programming PerlSearch this book

Chapter 13. Overloading

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.

13.1. The overload Pragma

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.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.











??????????????@Mail.ru