Оказывается, что простое добавление роли MooseX::Clone
в класс обеспечивает метод clone()
, который рекурсивно клонирует атрибуты.
- Для атрибутов hashref / arrayref он копирует структуры.
- Для скаляров (включая ссылки) он просто делает поверхностную копию ссылки.
- Если вы добавите
traits => ['Clone']
к атрибуту, он будет рекурсивно клонировать атрибут, вызвав clone()
для значения атрибута.
Чтобы поддержать клонирование Set::Object
, я создал черту CloneByCoercion
, подклассифицировав черту Clone
, параметризованную с типом, который будет приводиться к / от перед клонированием.
Итак, чтобы использовать его, я написал:
has 'blah' => (isa => 'Set::Object', is => rw,
traits => ['CloneByCoercion' => {to=>'ArrayRef'}]
);
MooseX::Types::Set::Object
обеспечивает приведения к ArrayRef и из него (хотя мне нужно было исправить ошибку в нем: приведение к ArrayRef должно возвращать ссылку, а неlist)
Я также изменил MooseX::Clone
, чтобы сохранить хэш, видимый объектами, чтобы он поддерживал клонирование структур связанных объектов с циклическими ссылками.
В конце концов я обойдудля размещения этого материала на CPAN или для отправки исправлений в модули.