Это потому, что объект DateTime (как и все объекты в Perl) является ссылкой.
$ perl -MDateTime -E'say overload::StrVal(DateTime->now)'
DateTime=HASH(0x55dad5805018)
(Обратите внимание, что я использовал overload::StrVal()
здесь как DateTime, перегружающий строковое преобразование - которое обычно очень полезно, но не здесь.)
Это большое шестнадцатеричное число является адресом памяти. Ваша переменная фактически не содержит данные DateTime, она хранит адрес в памяти данных DateTime (которые хранятся в ha sh).
Очевидный подход к получению копии вашего объекта DateTime примерно так:
my $obj1 = DateTime->now;
my $obj2 = $obj1;
Но это не очень полезно, поскольку $obj1
и $obj2
теперь оба содержат одинаковую ссылку на адрес памяти . Поэтому, если вы обновите одну из ссылок, вы увидите те же изменения, которые отражены в другой ссылке.
По этой причине класс DateTime включает метод clone()
. Это копирует ваш оригинальный объект в новую ячейку памяти и возвращает ссылку на новую копию. Затем вы можете изменить новую копию без изменения оригинала.
my $obj1 = DateTime->now;
my $obj2 = $obj1->clone;
Эта программа демонстрирует проблему (и решение).
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use DateTime;
say 'standard copy assignment';
my $obj1 = DateTime->now;
my $obj2 = $obj1;
say 'before changing $obj1';
say $obj1;
say $obj2;
$obj1->add(days => 1);
say 'after changing $obj1';
# Both dates are changed
say $obj1;
say $obj2;
say 'using clone()';
$obj1 = DateTime->now;
$obj2 = $obj1->clone;
say 'before changing $obj1';
say $obj1;
say $obj2;
$obj1->add(days => 1);
say 'after changing $obj1';
# Only $obj1 is changed
say $obj1;
say $obj2;