Как я могу определить поведение до/после увеличения в объектах Perl?

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

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

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

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


person Zaid    schedule 03.05.2010    source источник
comment
Я проверил, и, видимо, это не обман. +1 за вопрос, который, вероятно, должен был быть здесь давным-давно.   -  person Chris Lutz    schedule 03.05.2010


Ответы (2)


Вы хотите 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
person darch    schedule 03.05.2010
comment
Спасибо за редактирование, cjm; теперь я знаю соглашение о ссылке на документы. :) - person darch; 03.05.2010
comment
+1 Хороший пример. Вы можете сделать поведение ++ нестандартным, чтобы другие могли увидеть/почувствовать разницу - person Zaid; 03.05.2010

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

package SomeThing;

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

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

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

person Chris Lutz    schedule 03.05.2010
comment
О, это ужасное название для FAQ. Это также довольно плохой ответ. Добавлю в список того, что нужно исправить. - person brian d foy; 03.05.2010