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

Hello Wise Monks,

I'm a little new to perl and I've run into a little problem working with 2d arrays that seems simple but I've tried it many different ways I run into the same problem over and over again.

#!\usr\perl\bin -w use strict; use warnings; open FILE, "<", "SandSim.txt"; my @sandGrid; while(my $line = <FILE>){ chomp($line); push(@sandGrid, split('', $line)); } close FILE; printSand(@sandGrid); sub printSand{ my @array2d = @_; for my $i (0..$#array2d){ for my $j (0..$#array2d){ print "$array2d[$i][$j]"; } print "\n"; } }

I run into the same runtime error when I run the code.

 Can't use string(".") as an ARRAY ref while "strict refs" in use at FallingSand.pl line 21.

Here's the file I'm taking the data from if that helps:

..... # # .

I don't seem to have making the file into a 2d array but I just can't print it.

Replies are listed 'Best First'.
Re: Problem with traversing a two dimensional array
by robby_dobby (Hermit) on Jan 16, 2014 at 05:24 UTC
    Anon already gave you the correct answer to fix your problem. However, there's one other thing you should note:
    • You are iterating over the same range - 0..$#array2d for the two(row and column) indices. That means you should have an array that is of equal dimensions. In your case, you have a 6x5 array - make it 6x6 or 5x5.
Re: Problem with traversing a two dimensional array
by NetWallah (Canon) on Jan 16, 2014 at 05:53 UTC
    Following up on what robby_dobby explained - you could re-write your print loop more perlishly, and allow variable dimensions :
    sub printSand{ for my $inner_arrayref (@_){ for my $inner_element (@$inner_arrayref){ print $inner_element; } print "\n"; } }
    Of course, it would be more efficient to join the inner element, and print them together, replacing the inner loop with:
    print join("",@$inner_arrayref),"\n";
    and get rid of the separate print newline.

            If your eyes hurt after you drink coffee, you have to take the spoon out of the cup.
                  -Norm Crosby

Re: Problem with traversing a two dimensional array
by hdb (Monsignor) on Jan 16, 2014 at 08:43 UTC

    If you want to read your whole file into an array anyway, you can use <FILE> in list context to get the whole file in one go. Use map to translate each line into the desired array reference.

    my @sandGrid = map { chomp; [ split '', $_ ] } <FILE>;

    In the end it does the same thing as a loop but in a more compact way. Whether this suits your style you need to decide yourself.

    Either way, it is always useful to use Data::Dumper to inspect what you've got:

    use Data::Dumper; ... print Dumper \@sandGrid;
Re: Problem with traversing a two dimensional array (to create an arrayref use [ ] )
by Anonymous Monk on Jan 16, 2014 at 04:56 UTC

    split returns a list, to make an array you need [ 'square' , 'brackets' ]

    for exampe  push @sandGrid, [ split '', $line ];

    Say it with me:

    { 'hashes', 'are', 'curly', 'ones' }

    [ 'arrays', 'are', 'square' ]

    ( 'lists are round' )

      Hmm, the solution is correct but, in my view, the explanation seems to miss the main point: the main point is that, to construct an AoA, what needs to be pushed onto the larger array is not a list nor an array, but an array reference, and the sqare bruckets acts in this case as an array reference constructor.

        Hmm, the solution is correct but, in my view, the explanation seems to miss the main point:

        I don't think so Laurent_R, that is impossible
        The error message says Can't use string(".") as an ARRAY ref
        My answer title says (to create an arrayref use [ ] )
        My answer says split returns a list, to make an array you need [ 'square' , 'brackets' ]

        your view is tiny