2016-07-26 9 views
4

Есть ли в Perl 6 встроенный инструмент для создания глубокой копии вложенной структуры данных?Имеет ли Perl 6 встроенный инструмент для создания глубокой копии вложенной структуры данных?

Добавлен пример:

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" 

ответ

5
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; 

Использование .clone и deepmap запросить копию/глубокую копию структуры данных. Но не делайте ставку на это. Любой объект может определить его на методе clone и делать с ним все, что захочет. Если вы должны мутировать и поэтому должны клонировать, убедитесь, что вы тестируете свою программу с большими наборами данных. Плохие алгоритмы могут сделать программу практически бесполезной при производстве.

+0

Возможно, было бы хорошо показать * как использовать 'deepmap' с клоном – Borodin

+0

Связывание не требуется. Там швы будут где-то ошибкой. –

+1

ENOBUG. глубокая карта в сочетании с клоном будет выполнять задание. см .: http://irclog.perlgeek.de/perl6/2016-07-26#i_12912861 –

2

Грязный путь:

#!/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; 

, который дает вам:

$ 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}}} 

Если вы Eval вход от внешнего источника, всегда помнить, чтобы проверить его первым. В любом случае использование EVAL опасно и его следует избегать.