views:

104

answers:

2

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.

+7  A: 

If you look up perlfaq7 you'll find that the answer is to use the overload pragma, though they probably could have given the FAQ question a better name (in my opinion).

package SomeThing;

use overload
  '+' => \&myadd,
  '-' => \&mysub;

Basically (assuming $a is an object of the SomeThing class and $b isn't), the above would overload $a + $b to be $a->myadd($b, 0) and $b + $a to $a->myadd($b, 1) (that is, the third argument is a boolean meaning "were the arguments to this operator flipped" and the first-argument-is-self syntax is preserved), and the same for - and mysub.

Read the documentation for the full explanation.

Chris Lutz
Cool! This opens up all sorts of possibilities...
Zaid
Huh, that is an awful title for a FAQ. It's also a pretty poor answer. I'll add it to my list of things to fix.
brian d foy
+11  A: 

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
darch
Thank you for the edit, cjm; now I know the link-to-docs convention. :)
darch
+1 Nice example. You may want to make the behavior of `++` non-standard so that others can see/feel the difference
Zaid