В Perl для глубокого копирования вложенных структур (например, хэши массивов, массивы хэшей) нельзя использовать простое присваивание или стандартные функции (@b = @a, %b = %a, $clone = $orig). Такие операции создают только поверхностную копию: вложенные объекты по-прежнему ссылаются на одни и те же области памяти.
Для глубокого копирования используют:
Storable:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone: аналогичное применение.Важно помнить: копируются все уровни вложенности, включая ссылки внутри структуры.
Что произойдет при простом присваивании сложной структуры данных: копируются ли вложенные элементы?
Ответ: Нет, копируется только верхний уровень. Внутренние массивы и хэши остаются разделяемыми между оригинальным и копией.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — тоже станет 99!
Только использование глубокого клонирования даст полностью независимую копию.
История 1
В REST API-приложении клонировали запросы для разных клиентов через обычное присваивание ссылки. В результате изменения ответа одного клиента моментально отражались у всех остальных — потому что все работали с одной и той же вложенной структурой данных.
История 2
При агрегировании данных сложной структуры массивов использовали копирование через push (push @new, @old), забывая про вложенные уровни. Случайное изменение вложенного хэша поломало данные всех агрегатов — баг долго не мог быть выявлен.
История 3
Для обработки логов в скрипте дублировали структуру через Clone, но не учли особые "магические" поля объектов — соответственно, потеряли необходимые методы/атрибуты. В итоге функциональность была невалидной, а ошибка воспроизвелась только на проде.