The default clone
inherited from Mu
is shallow, as documented. This means that it will only copy the object itself, but not anything the object references. It is possible to override clone
to have your preferred semantics, which is probably the best thing to do here.
One useful thing to know in doing this is that clone
takes named parameters and uses them to assign to properties of the cloned object. This is worth knowing because:
- One should make sure to handle this when overriding
clone
, to avoid surprises to users of the overridden clone
method who use this feature
- One can use this when overriding
clone
to succinctly opt in to cloning of a particular array or hash attribute
Thus for the case in the question, writing:
class A {
has @.a;
method clone() {
callwith(:@!a, |%_)
}
}
Will result in the output [1 2]
as presumably desired. How does it work?
- The |%_ just passes on any tweaks the caller of this
clone
method specified
:@!a
is short for a => @!a
callwith
calls the inherited clone
(from Mu
in this case)
- Assignment, not binding, semantics are used on
@!a
in the target object (just as during object construction), resulting in a copy of the array
This shortcut works for hash attributes too. For an attribute containing another object, it'd look like callsame(x => $!x.clone)
.