2015-04-21 1 views
0

Lorsque tableau passant à sous par référence, je dois cloner le tableau, parce que je ne veux pas tenir compte des changements de tableau local sur sous, donc je peux le faire:Quelle est la meilleure façon de cloner un tableau transmis par une référence en Perl?

$arrayref = shift; 
$arrayref = [ map { $_ } @$arrayref ]; 

Y at-il un meilleur, élégant une façon en ligne de le faire? Veuillez prendre note de la transmission d'un tableau par référence et de l'affectation d'une référence à un nouveau tableau à la même variable.

Répondre

3

map { $_ } est redondant. Faites simplement:

$arrayref = [ @$arrayref ]; 
3

Vous n'avez pas besoin de l'instruction map. Décrochez simplement votre arrayref avec le sigil @, créez un nouveau arrayref anonyme en utilisant les valeurs dé-référencées, puis affectez le résultat de cela à une nouvelle variable.

main::(-e:1): 0 
    DB<1> $a = [1,2,3]; 

    DB<2> x $a; 
0 ARRAY(0x7fe7cb80bd78) 
    0 1 
    1 2 
    2 3 
    DB<3> $b = [ @$a ]; 

    DB<4> x $b; 
0 ARRAY(0x7fe7cc0b9da0) # < different address 
    0 1 
    1 2 
    2 3 

Vous pouvez également envelopper ce dans un simple sous:

sub clone { 
    my $arrayref = shift; 

    croak 'Supplied argument is not an arrayref' 
     unless $arrayref && ref($arrayref) eq 'ARRAY'; 

    return [ @$arrayref ]; 
} 

Note: si votre structure de données a plus de 1 couche (par exemple des tableaux multidimensionnels) cette solution ne fonctionne pas, parce que les références internes resteront les mêmes. Il y a un joli module appelé Clone sur CPAN qui peut très bien gérer les structures de données imbriquées.

2

Vous pouvez tout faire en une seule commande:

my $clonedref = [ @{ shift() } ]; 

Notez qu'il clone que la couche supérieure de la référence de tableau, à savoir s'il existe des structures imbriquées dans le tableau, ils ne seront pas clonés.