Overloading Operators

Problem

You want to use familiar operators like == or + on objects from a class you’ve written, or you want to define the print interpolation value for objects.

Solution

Use the use overload pragma. Here are two of the most common and useful operators to overload:

use overload ('<=>' => \&threeway_compare);
sub threeway_compare {
    my ($s1, $s2) = @_;
    uc($s1->{NAME}) cmp uc($s2->{NAME});
} 

use overload ( '""'  => \&stringify );
sub stringify {
    my $self = shift;
    return sprintf "%s (%05d)", 
            ucfirst(lc($self->{NAME})),
            $self->{IDNUM};
}

Discussion

When you use built-in types, certain operators apply, like + for addition or . for string catenation. 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;

Now, those four operators can be used with objects of class TimeNumber, and the listed functions will be called. 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 called 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} ...

Get Perl Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.