in reply to Re: Array wierdness
in thread Array wierdness

Thanks for the explanation. FWIW, assigning the numbers to the arrays in separate lines makes no difference.

Replies are listed 'Best First'.
Re^3: Array wierdness
by Animator (Hermit) on Apr 25, 2022 at 15:36 UTC
    Just to elaborate a bit more on this, consider the code:
    my @PP = ("foo", "bar", "baz"); my @OO = ("AAA", "bar", "CCC"); $PP[1][0] = "foobar";
    What happens is that this does not modify the @PP array, instead it uses the value of $PP[1] as an array reference which points to the global(/package) variable @bar. To make this a bit clearer:
    #!/usr/bin/perl -l my @PP = ("foo", "bar", "baz"); my @OO = ("AAA", "bar", "CCC"); $PP[1][0] = "foobar"; print "\@PP: " . join(", ", @PP); print "\@OO: " . join(", ", @OO); print "\@bar: " . join(", ", @::bar);
    Output:
    @PP: foo, bar, baz
    @OO: AAA, bar, CCC
    @bar: foobar
    
    The '@PP' and '@OO' array are unmodified; the '@bar' array however was created.

    With use strict; you get the error: Can't use string ("bar") as an ARRAY ref while "strict refs" in use

Re^3: Array wierdness
by pryrt (Abbot) on Apr 25, 2022 at 15:34 UTC
    FWIW, assigning the numbers to the arrays in separate lines makes no difference.

    This is because your code's comments are wrong:

    # fill two 25 x 25 arrays with zeros, then modify a couple of cells my @PP = my @OO = (1..25);

    This does not create 25x25 arrays, this creates 1x25 arrays.

    Below shows a 1x25 (what you have) vs a 2x5:

    use strict; use warnings; use Data::Dump; my @one_by_twentyfive = (1..25); my @two_by_five = ([1..5],[1..5]); dd \@one_by_twentyfive; dd \@two_by_five; __END__ [1 .. 25] [[1 .. 5], [1 .. 5]]

    or this one populates a 25x25 array, then overrides 3 slots:

      Hello,

      you can also initialize an ArrayOfArrays setting default values using x (repetition operator in list context) like in:  @aoa = ([( 1 ) x 3]) x 3

      L*

      PS I evidently need more coffeine this morning.. see below

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

        That's usually not what you want: that'll give you three copies of the same arrayref, so if you later modify an element in one row it'll modify it in all rows:

        % perl -wle '@aoa = ([(1) x 3]) x 3; $aoa[1][2] = 3; print "@$_" for @ +aoa' 1 1 3 1 1 3 1 1 3

        If you want each element to be independent, a typical approach is to pass it through map:

        % perl -wle '@aoa = map [(1) x 3], 1..3; $aoa[1][2] = 3; print "@$_" f +or @aoa' 1 1 1 1 1 3 1 1 1
Re^3: Array weirdness
by LanX (Saint) on Apr 26, 2022 at 10:25 UTC
    short answer

    print this on a t-shirt:

    and wear it at work. ;-)

    long answer

    $PP[1][2]=3 is a shorter notation for $PP[1]->[2] = 3

    so with

    $PP[1] == $OO[1] == 1

    what you are effectively doing is

    1->[2] = 3

    which is just populating @1

    debugger-demo perl -de0

    DB<46> 1->[2] = 3 DB<47> x @1 0 undef 1 undef 2 3 DB<48>

    For good reasons that's forbidden under strict

    DB<45> use strict; my @PP; $PP[1]=1; $PP[1][2] = 3 Can't use string ("1") as an ARRAY ref while "strict refs" in use at ( +eval 66) ...

    > FWIW, assigning the numbers to the arrays in separate lines makes no difference.

    Well I hope it's now clearer why...

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery