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

I am trying to use unshift with two dimensional arrays but have some peculiear reference thing going on?
@a=([0,1,2]); @b=([-1,-2,-3]); unshift @a,1; $a[0][0]=4; $a[0][1]=5; $a[0][2]=6; unshift (@b,1); $b[0][0]=7; $b[0][1]=8; $b[0][2]=9; print $a[0][2]; print $a[1][2]; print $b[0][2]; print $b[1][2];
running this code gives 9 2 9 -3.
I would expect 6 2 9 -3
Why is the redefining of @b changing the values in @a??

Replies are listed 'Best First'.
Re: unshift with two-dimensional arrays
by ikegami (Patriarch) on Oct 26, 2007 at 11:12 UTC

    Please use use strict. Not using it hides errors, including the one you made.

    use strict; use warnings; my @a=([0,1,2]); my @b=([-1,-2,-3]); unshift @a,1; # Creates an element with the value "1". $a[0][0]=4; # Changes element 0 of the array named by $a[0]. $a[0][1]=5; # Changes element 1 of the array named by $a[0]. $a[0][2]=6; # Changes element 2 of the array named by $a[0]. unshift (@b,1); # Creates an element with the value "1". $b[0][0]=7; # Changes element 0 of the array named by $b[0]. $b[0][1]=8; # Changes element 1 of the array named by $b[0]. $b[0][2]=9; # Changes element 2 of the array named by $b[0]. print $a[0][2]; # Print element 2 of the array named by $a[0]. print $a[1][2]; # Print element 2 of the array ref'ed by $a[1]. print $b[0][2]; # Print element 2 of the array named by $b[0]. print $b[1][2]; # Print element 2 of the array ref'ed by $b[1].
    Can't use string ("1") as an ARRAY ref while "strict refs" in use at s +cript.pl line 8.

    If you want to add a new row, use unshift @a, [ ];.

    unshift @a, [ ]; $a[0][0]=4; $a[0][1]=5; $a[0][2]=6;

    or

    unshift @a, [ 4, 5, 6 ];
    [ ] creates an anonymous array and returns a reference.
Re: unshift with two-dimensional arrays
by johngg (Canon) on Oct 26, 2007 at 11:20 UTC
    It can be helpful to use Data::Dumper to visualise your data if you are not sure what is going wrong.

    use strict; use warnings; use Data::Dumper; my @arrA = ( [0, 1, 2] ); unshift @arrA, 1; print Data::Dumper->Dump([\@arrA], [q{*arrA}]); shift @arrA; unshift @arrA, [1]; print Data::Dumper->Dump([\@arrA], [q{*arrA}]);

    This code produces the following.

    @arrA = ( 1, [ 0, 1, 2 ] ); @arrA = ( [ 1 ], [ 0, 1, 2 ] );

    I hope this is useful.

    Cheers,

    JohnGG

Re: unshift with two-dimensional arrays
by jettero (Monsignor) on Oct 26, 2007 at 10:56 UTC

    You may be surprised to learn that @a=([0,1,2]); creates an array with one element in it. The first scalar in @a is an arrayref. that array ref has three elements.

    You probably want to do  unshift @a, [1]. Now @a is an array with two elements in it. Both are scalary array refs.

    See perlref for all the magic. I used to read that page quite often (probably twice a year or more).

    -Paul

Re: unshift with two-dimensional arrays
by syphilis (Archbishop) on Oct 26, 2007 at 12:56 UTC
Re: unshift with two-dimensional arrays
by Anonymous Monk on Oct 26, 2007 at 18:02 UTC

    To be pedantic, Perl doesn't have multi-dimensional arrays; it has arrays where the elements can be references to other arrays (or hashes or any other data structure), so pop and unshift will remove an array element, which would happen to be a reference.

      so pop and unshift will remove an array element
      I'm quite sure you meant to say pop and shift.

      -David