@@ -162,9 +162,9 @@ Returns the object it is called on.
162
162
163
163
method clone(*%twiddles)
164
164
165
- Creates a shallow clone of the invocant. Alternative values for I < public >
166
- attributes can be provided via named arguments with names matching the
167
- attributes' names.
165
+ Creates a shallow clone of the invocant, including shallow cloning of private
166
+ attributes. Alternative values for I < public > attributes can be provided via
167
+ named arguments with names matching the attributes' names.
168
168
169
169
= begin code
170
170
class Point2D {
@@ -180,6 +180,57 @@ say $p; # OUTPUT: «Point(2, 3)»
180
180
say $p.clone(y => -5); # OUTPUT: «Point(2, -5)»
181
181
= end code
182
182
183
+ Note that C < .clone > does not go the extra mile to shallow-copy C < @. > and C < %. >
184
+ sigiled attributes and, if modified, the modifications will still be available
185
+ in the original object:
186
+
187
+ = begin code
188
+ class Foo {
189
+ has $.foo is rw = 42;
190
+ has &.boo is rw = { say "Hi" };
191
+ has @.bar = <a b>;
192
+ has %.baz = <a b c d>;
193
+ }
194
+
195
+ my $o1 = Foo.new;
196
+ with my $o2 = $o1.clone {
197
+ .foo = 70;
198
+ .bar = <Z Y>;
199
+ .baz = <Z Y X W>;
200
+ .boo = { say "Bye" };
201
+ }
202
+
203
+ # Hash and Array attribute modifications in clone appear in original as well:
204
+ say $o1; # OUTPUT: «Foo.new(foo => 42, bar => ["Z", "Y"], baz => {:X("W"), :Z("Y")}, …»
205
+ say $o2; # OUTPUT: «Foo.new(foo => 70, bar => ["Z", "Y"], baz => {:X("W"), :Z("Y")}, …»
206
+ $o1.boo.(); # OUTPUT: «Hi»
207
+ $o2.boo.(); # OUTPUT: «Bye»
208
+ = end code
209
+
210
+ To clone those, you could implement your own C < .clone > that clones the
211
+ appropriate attributes and passes the new values to C < Mu.clone > , for example,
212
+ via L < nextwith > . Alternatively, your own C < .clone > could clone self first
213
+ (using C < self.Mu::clone > or L < callsame > ) and then manipulate the clone as needed,
214
+ before returning it.
215
+
216
+ = begin code
217
+ class Bar {
218
+ has @.foo = <a b>;
219
+ has %.bar = <a b c d>;
220
+ method clone { nextwith :foo(@!foo.clone) :bar(%!bar.clone) }
221
+ }
222
+
223
+ my $o1 = Bar.new;
224
+ with my $o2 = $o1.clone {
225
+ .foo = <Z Y>;
226
+ .bar = <Z Y X W>;
227
+ }
228
+
229
+ # Hash and Array attribute modifications in clone do not affect original:
230
+ say $o1; # OUTPUT: «Bar.new(foo => ["a", "b"], bar => {:a("b"), :c("d")})»
231
+ say $o2; # OUTPUT: «Bar.new(foo => ["Z", "Y"], bar => {:X("W"), :Z("Y")})»
232
+ = end code
233
+
183
234
= head2 method new
184
235
185
236
multi method new(*%attrinit)
0 commit comments