Search code examples
perlobjectdecrement

How can I define pre/post-increment behavior in Perl objects?


Date::Simple objects display this behavior, where $date++ returns the next day's date.

Date::Simple objects are immutable. After assigning $date1 to $date2, no change to $date1 can affect $date2. This means, for example, that there is nothing like a set_year operation, and $date++ assigns a new object to $date.

How can one custom-define the pre/post-incremental behavior of an object, such that ++$object or $object-- performs a particular action?

I've skimmed over perlboot, perltoot, perltooc and perlbot, but I don't see any examples showing how this can be done.


Solution

  • You want overload.

    package Number;
    
    use overload
        '0+'    => \&as_number,
        '++'    => \&incr,
    ;
    
    sub new {
        my ($class, $num) = @_;
    
        return bless \$num => $class;
    }
    
    sub as_number {
        my ($self) = @_;
    
        return $$self;
    }
    
    sub incr {
        my ($self) = @_;
    
        $_[0] = Number->new($self->as_number + 1); # note the modification of $_[0]
        return;
    }
    
    package main;
    
    my $num = Number->new(5);
    print $num      . "\n"; # 5
    print $num++    . "\n"; # 5
    print ++$num    . "\n"; # 7