Значение по умолчанию clone
, унаследованное от Mu
, является мелким, как описано в документации. Это означает, что он будет копировать только сам объект, но не все, на что ссылается объект. Можно переопределить clone
, чтобы иметь предпочитаемую семантику, что, вероятно, лучше всего сделать здесь.
При этом полезно знать, что clone
принимает именованные параметры и использует их для назначения свойств клонированного объекта. Это стоит знать, потому что:
- Нужно обязательно учитывать это при переопределении
clone
, чтобы избежать неожиданностей для пользователей переопределенного метода clone
, которые используют эту функцию
- Это можно использовать при переопределении
clone
, чтобы кратко включить клонирование определенного массива или хеш-атрибута
Таким образом, для рассматриваемого случая пишем:
class A {
has @.a;
method clone() {
callwith(:@!a, |%_)
}
}
Результатом будет [1 2]
, как и предполагалось. Как это работает?
- |% _ просто передает любые изменения, вызывающие этот
clone
метод, указанный
:@!a
- это сокращение от a => @!a
callwith
вызывает унаследованный clone
(от Mu
в данном случае)
- Назначение, без привязки, семантика используется на
@!a
в целевом объекте (так же, как и при построении объекта), в результате чего получается копия массива
Этот ярлык работает и для хеш-атрибутов. Для атрибута, содержащего другой объект, он будет выглядеть как callsame(x => $!x.clone)
.