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

$a[7][9] = {' ',' ',' ','#','#','#',' ',' ',' '} {' ',' ','#','#',' ','#','#',' ',' '} {' ','#','#',' ',' ',' ','#','#',' '} {'#','#',' ',' ',' ',' ',' ','#','#'} {'#','#','#','#','#','#','#','#','#'} {'#','#',' ',' ',' ',' ',' ','#','#'} {'#','#',' ',' ',' ',' ',' ','#','#'};
What's wrong with this?

Replies are listed 'Best First'.
Re: Multidimensional Array
by Zaxo (Archbishop) on Jun 23, 2002 at 03:20 UTC

    Syntax errors from the absence of commas between lists, and a surprise from trying to dimension the array. You are assigning to one element of the array.

    A multidimensional array in Perl is a one-dimensional array of references to arrays. What you mean to write is:

    my @a = ( [' ',' ',' ','#','#','#',' ',' ',' '], [' ',' ','#','#',' ','#','#',' ',' '[, [' ','#','#',' ',' ',' ','#','#',' '], ['#','#',' ',' ',' ',' ',' ','#','#'], ['#','#','#','#','#','#','#','#','#'], ['#','#',' ',' ',' ',' ',' ','#','#'], ['#','#',' ',' ',' ',' ',' ','#','#'] );

Re: Multidimensional Array
by Juerd (Abbot) on Jun 23, 2002 at 10:00 UTC

    What's wrong with this?

    Just that Perl often Does What You Mean, doesn't mean you can just go try syntaxes you already know from other languages. If you want to do something you haven't done in Perl before, you should read documentation, because code like this is very unlikely to work. I suggeset you read the following documents:

    Good luck finding out how Perl works.

    Your code doesn't work for several reasons.

    • Arrays are sized automatically in Perl, so with $foo[4], you're already using the fifth element of @foo. With $foo[4][8], you're using the ninth element of the array that is referenced to in the fifth element of @foo. To assign to @foo, use @foo.
    • Anonymous array references are made with square brackets, not curlies. Perl does not have multidimentional arrays natively, but it can have arrays that hold references to other arrays. When not naming them, they are anonymous.
    • Elements need to be separated with commas.
    Here's an example matrix in Perl:
    @foo = ( [1, 2, 3], [4, 5, 6], [7, 8, 9] ); print $foo[2][1]; # prints 8

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

Re: Multidimensional Array
by kvale (Monsignor) on Jun 23, 2002 at 03:20 UTC
    It looks like you are trying to initialize a matrix, but do not have the syntax correct. Try
    #!/usr/bin/perl -w $a = [ [' ',' ',' ','#','#','#',' ',' ',' '], [' ',' ','#','#',' ','#','#',' ',' '], [' ','#','#',' ',' ',' ','#','#',' '], ['#','#',' ',' ',' ',' ',' ','#','#'], ['#','#','#','#','#','#','#','#','#'], ['#','#',' ',' ',' ',' ',' ','#','#'], ['#','#',' ',' ',' ',' ',' ','#','#'] ]; print "$a->[4][0]\n";
    This sets $a to an anonymous array of arrays - the braces you used are for hashes, and dimensioning is not needed.
Re: Multidimensional Array
by grinder (Bishop) on Jun 23, 2002 at 21:25 UTC
    Gack, that's an awful lot of punctuation to get right. I would lean towards using Perl's quoteword facility, it would make things much easier to read.

    That is, of course, if you can live with the idea of changing spaces to dots. Consider:

    my @a = ( [qw/. . . # # # . . ./], [qw/. . # # . # # . ./], [qw/. # # . . . # # ./], [qw/# # . . . . . # #/], [qw/# # # # # # # # #/], [qw/# # . . . . . # #/], [qw/# # . . . . . # #/], );

    Of course, if you really do need spaces instead of dots in your array entry, you shall have to map the dots back to spaces:

    my @a = ( [map{tr/./ /;$_} qw/. . . # # # . . ./], [map{tr/./ /;$_} qw/. . # # . # # . ./], [map{tr/./ /;$_} qw/. # # . . . # # ./], [map{tr/./ /;$_} qw/# # . . . . . # #/], [map{tr/./ /;$_} qw/# # # # # # # # #/], [map{tr/./ /;$_} qw/# # . . . . . # #/], [map{tr/./ /;$_} qw/# # . . . . . # #/], );

    Then again, that still looks too stretched out to help you easily comprehend what's in the array. And it's not really much simpler than what you had initially. Better, then, to use a different approach, this time using split.

    my @a = ( [split //, q/ ### /], [split //, q/ ## ## /], [split //, q/ ## ## /], [split //, q/## ##/], [split //, q/#########/], [split //, q/## ##/], [split //, q/## ##/], );

    As an added bonus, this way we get our spaces back. Short, sharp and sweet.

    By the way, get into the habit of adding a trailing comma on the last element of an array. Perl will silently ignore it, and it really comes in handy when you decide to add to or remove the last array element. Basically, you just don't have to worry any more, and it gives all the lines a pleasing symmetry.


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'