Как определить поведение pre/post-increment в объектах Perl?

Date::Simple объекты отображают это поведение, где $date++ возвращает дату следующего дня.

Дата:: Простые объекты неизменяемы. После присвоения $date1 до $date2 никакие изменения в $date1 не могут повлиять на $date2. Это означает, например, что нет ничего похожего на операцию set_year, а $date ++ присваивает новый объект $date.

Как можно настроить пользовательское определение pre/post-incremental поведения объекта, так что ++$object или $object-- выполняет конкретное действие?

Я просмотрел perlboot, perltoot, perltooc и perlbot, но я не вижу примеров, показывающих, как это можно сделать.

Ответы

Ответ 1

Вы хотите 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

Ответ 2

Если вы посмотрите perlfaq7, вы обнаружите, что ответ заключается в использовании overload pragma, хотя они, вероятно, могли бы задавать вопрос с вопросом, лучше имя (на мой взгляд).

package SomeThing;

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

В принципе (предполагая, что $a является объектом класса SomeThing, а $b - нет), вышеуказанное перегружает $a + $b как $a->myadd($b, 0) и $b + $a в $a->myadd($b, 1) (то есть, третий аргумент является логическим значением "были аргументы для этого оператора перевернуты", а синтаксис с первым аргументом - есть), и то же самое для - и mysub.

Прочитайте документацию для полного объяснения.