13.14.3. Discussion
When you use built-in types, certain operators apply, like
+ for addition or . for string
concatenation. With the use
overload pragma, you can customize these operators
so they do something special on your own objects.
This pragma takes a list of operator/function call pairs, such as:
package TimeNumber;
use overload '+' => \&my_plus,
'-' => \&my_minus,
'*' => \&my_star,
'/' => \&my_slash;
Those four operators can now be used with objects of class
TimeNumber, and the listed functions will be called as method
invocations. These functions can do anything you'd like.
Here's a simple example of an overload of + for
use with an object that holds hours, minutes, and seconds. It assumes
that both operands are of a class that has a new
method that can be invoked as an object method, and that the
structure names are as shown:
sub my_plus {
my($left, $right) = @_;
my $answer = $left->new( );
$answer->{SECONDS} = $left->{SECONDS} + $right->{SECONDS};
$answer->{MINUTES} = $left->{MINUTES} + $right->{MINUTES};
$answer->{HOURS} = $left->{HOURS} + $right->{HOURS};
if ($answer->{SECONDS} >= 60) {
$answer->{SECONDS} %= 60;
$answer->{MINUTES} ++;
}
if ($answer->{MINUTES} >= 60) {
$answer->{MINUTES} %= 60;
$answer->{HOURS} ++;
}
return $answer;
}
It's probably best to overload numeric operators only when the
objects themselves are mirroring some sort of inherently numeric
construct, such as complex or infinite precision numbers, vectors, or
matrices. Otherwise, the code becomes hard to understand and might
lead users to invalid assumptions. Imagine a class that modeled a
country. If you can add one country to another, couldn't you subtract
one country from another? Applying overloaded mathematical operators
for non-mathematical objects rapidly becomes ridiculous.
You may compare objects (and, in fact, any reference) using either
= = or eq, but this only tells
you whether the addresses are the same. (Using = =
is about 10 times faster than eq though.) Because
an object is a higher-level notion than a raw machine address, you
often want to define your own notion of what it takes for two of them
to be considered equal.
Two operators frequently overloaded even for a non-numeric class are
the comparison and string interpolation operators. Both the <=>
and the cmp operators can be overloaded, although
the former is more prevalent. Once the spaceship operator <=>
is defined for an object, you can use = =,
!=, <,
<=, >, and
>= as well. This lets objects be collated. If
ordering is not desired, overload only = =.
Similarly, an overloaded cmp is used for
lt, gt, and other string
comparisons if they aren't explicitly overloaded.
The string interpolation operator goes by the unlikely name of
"", that is, two double quotes. This operator is
triggered whenever a conversion to a string is called for, such as
within double or back quotes or when passed to the
print function.
Read the documentation on the overload pragma that
comes with Perl or Chapter 13 of Programming
Perl. Perl's operator overloading has some elaborate
features, such as string, numeric, and Boolean conversion methods,
autogeneration of missing methods, and reversing operands if needed,
as in 5 + $a
where $a is an object.