sid_com
sid_com

Reputation: 25117

Does Perl 6 have a built-in tool to make a deep copy of a nested data structure?

Does Perl 6 have a built-in tool to make a deep copy of a nested data structure?

Added example:

my %hash_A = (
    a => {
        aa => [ 1, 2, 3, 4, 5 ],
        bb => { aaa => 1, bbb => 2 },
    },
);


my %hash_B = %hash_A;
#my %hash_B = %hash_A.clone; # same result

%hash_B<a><aa>[2] = 735;

say %hash_A<a><aa>[2]; # says "735" but would like get "3"

Upvotes: 7

Views: 379

Answers (2)

user5854207
user5854207

Reputation:

my %A = (
    a => {
        aa => [ 1, 2, 3, 4, 5 ],
        bb => { aaa => 1, bbb => 2 },
    },
);

my %B = %A.deepmap(-> $c is copy {$c}); # make sure we get a new container instead of cloning the value

dd %A;
dd %B;

%B<a><aa>[2] = 735;

dd %A;
dd %B;

Use .clone and .deepmap to request a copy/deep-copy of a data-structure. But don't bet on it. Any object can define its own .clone method and do whatever it wants with it. If you must mutate and therefore must clone, make sure you test your program with large datasets. Bad algorithms can render a program virtually useless in production use.

Upvotes: 9

cuonglm
cuonglm

Reputation: 2816

The dirty way:

#!/usr/local/bin/perl6

use v6;
use MONKEY-SEE-NO-EVAL;

my %hash_A = (
    a => {
        aa => [ 1, 2, 3, 4, 5 ],
        bb => { aaa => 1, bbb => 2 },
    },
);


my %hash_B;
EVAL '%hash_B = (' ~ %hash_A.perl ~ ' )';

%hash_B<a><aa>[2] = 735;

say %hash_A;
say %hash_B;

which gives you:

$ perl6 test.p6
{a => {aa => [1 2 3 4 5], bb => {aaa => 1, bbb => 2}}}
{a => {aa => [1 2 735 4 5], bb => {aaa => 1, bbb => 2}}}

If you eval input from external source, always remember to check it first. Anyway, using EVAL is dangerous and should be avoided.

Upvotes: 3

Related Questions