role MutableMethods[&obs] {
method _mutable(::?CLASS $obj, \ret) {
&obs.($obj);
ret
}
}
multi trait_mod:<is>(Method $m, :$mutable!) {
$m.wrap: method (|) {
my \ret = callsame;
do if self ~~ MutableMethods && ret ~~ List && ret.head ~~ self.WHAT {
$._mutable: |ret
} else {
ret
}
}
}
class C {
has Int $.value;
method incr is mutable {
$.clone(:value($!value + 1)),
1
}
}
sub mutate(@objs, &block) {
my @lex is List = do for @objs <-> $obj {
my $o = $obj but MutableMethods[{
$o = $_
}];
}
block |@lex;
@objs.kv.map: -> $i, $obj {
my $o = @lex[$i];
$obj.new:
|$o.^attributes.map({
.name.substr(2) => .get_value: $o
}).Map
}
}
my $c = C.new: :1value;
my $d = C.new:10value;
say mutate ($c, $d), <-> $c, $d {
$c.say;
say $c.incr;
$c.say;
say $c.value;
say $d.incr;
$d.say;
say $d.value;
}
say $c;