dda has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

Please look at the code example:

#!/usr/bin/perl -w use strict; my @a = (1,2,3,4); my $p = \@a; print "before:\n"; foreach (@{$p}) { print "element $_\n"; } @a = (); print "after:\n"; foreach (@{$p}) { print "element $_\n"; }
What if I want to keep the old contents somewhere? I found that changing the line
my $p = \@a;
to
my $p = [@a];
does the trick. Is it a correct way?

--dda

Replies are listed 'Best First'.
Re: Duplicating array contents
by jdporter (Paladin) on Dec 16, 2002 at 15:10 UTC
    Well, you understand that  $p = \@a; makes $p be a reference to the array @a, right? That means if you alter @a in any way, @$p is altered as well, and vice versa.
    If your point is really to create a new, indpendent copy of the contents of an array, you would simply do this:
    @b = @a;

    You may indeed do  $p = [ @a ]; with the understanding that $p is now a reference to a copy of @a.

    jdporter
    ...porque es dificil estar guapo y blanco.

(jeffa) Re: Duplicating array contents
by jeffa (Bishop) on Dec 16, 2002 at 15:12 UTC
    Without knowing what you are doing, saying that your 'trick' is or is not a correct way is next to impossible. If you want to keep the old contents, you have to make a copy. If you want to work with a reference to the array, you have to account for the fact that those contents can be altered.
    my $p = \@a;
    Now $p is a reference to @a. You can change the contents of @a via $p.
    my $p = [@a];
    $p is still a reference, but a reference to an anonymous array that contains the contents of @a. You can change the contents of $p, but that will not affect @a (as long as @a didn't contain any references ... we won't go there). You could also copy @a like so:
    my @p = @a;
    Instead of merely printing the contents out, i find using Data::Dumper to be much more helpful:
    use strict; use warnings; use Data::Dumper; my @a = (1,2,3,4); my @copy = @a; my $ref = \@a; my $refcopy = [@a]; @a = (); print "orginal: ", Dumper \@a; print "array copy: ", Dumper \@copy; print "reference: ", Dumper $ref; print "ref copy: ", Dumper $refcopy;

    UPDATE:
    This is Perl, so instead of using the cluttered:

    foreach (@{$p}) { print "element $_\n"; }
    use the more readable (IMHO at least):
    print "element $_\n" for @$p;
    Have fun. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Or since this is Perl, print map "element $_\n", @$p; ;-)

      Makeshifts last the longest.

Re: Duplicating array contents
by BrowserUk (Patriarch) on Dec 16, 2002 at 15:12 UTC

    That is one way to take a copy of an array. With that line added to your your program, it is effectively equivalent to:

    #!/usr/bin/perl -w use strict; my @a = (1,2,3,4); my @p = @a; print "before:\n"; foreach (@p) { print "element $_\n"; } @a = (); print "after:\n"; foreach (@p) { print "element $_\n"; }

    Examine what is said, not who speaks.