http://www.perlmonks.org?node_id=880118

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

Hi,

Just starting out in perl, was hoping someone can explain why this code from a tutorial isn't working...

#!/usr/bin/perl use strict; use warnings; my @compass = { ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] }; print $compass[0]->[1]; >Odd number of elements in anonymous hash at array_compass.pl line 4. >Not an ARRAY reference at array_compass.pl line 11.

using perl v5.12.1 built for x86_64-linux-thread-multi on OpenSUSE.

Must be something simple but after a couple of hours searching, reading and trying different things still can't work it out??

Thanks

Replies are listed 'Best First'.
Re: simple array question
by eyepopslikeamosquito (Archbishop) on Jan 03, 2011 at 03:21 UTC

    You need to use () and not {} when you define the @compass array, like this:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @compass = ( ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] ); print Dumper(\@compass);

Re: simple array question
by philipbailey (Curate) on Jan 03, 2011 at 03:22 UTC

    It seems that you are trying to assign a list to array @compass. Lists are surrounded by brackets, or parentheses if you prefer that term: (). Instead, you have used braces, which in this case create a reference to an anonymous hash, hence the warning messages.

    So you need something more like this:

    #!/usr/bin/perl use strict; use warnings; my @compass = ( ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"], ); print $compass[0]->[1];
      Lists are surrounded by brackets....

      Not rvalue lists! Commas, not parentheses, produce literal rvalue lists. The three array references in this variant of that code are a list just as much as in the original version:

      my @compass = ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"], ;

      The difference between the two examples is the precedence of the assignment operator compared to the precedence of the comma operators.

      thanks greatly that worked!

      it is nice to have some help when starting, may have been a while before I finally got it.

      seems that some code has { or [ also

      is that a typo or a perl version thing or OS thing or am I still missing something? thanks again

Re: simple array question
by GrandFather (Saint) on Jan 03, 2011 at 06:09 UTC

    By now you have the help you were looking for, but it may help a little to understand why Perl works like that. Larry Wall designed parts of Perl with the idea that different things should look different. That is a reason why Perl uses $, @ and % in front of variables and things. Things that have $ in front act like scalar values (numbers, strings and stuff like that). Things that have @ in front act like arrays or lists of things (don't get hung up about the difference at this point though). Things that have % in front act like hashes (those are really important to understand in Perl, but cause a lot of initial grief for beginners).

    Arrays and hashes are both indexed variables - they hold lots of stuff and you need an index to select the particular element you are interested in. Arrays are indexed using numbers starting from 0 using syntax that looks like: $array[$index]. The $ out the front tells you that you are getting a scalar value. The [$index] bit selects the element 'indexed' by the numeric value in $index.

    Hashes are indexed by strings. Accessing an element of a hash looks like: $hash{$index}. Still the $ out front to tell use we are getting a scalar value, but now we use curly brackets instead of square brackets and now $index contains any string we care to use.

    Of course there is a whole lot more to it than that which you will learn along the way. Just remember that in general Perl tries to make things that are different look different.

    True laziness is hard work
Re: simple array question
by toolic (Bishop) on Jan 03, 2011 at 04:14 UTC
      Thanks all for very helpful and speedy replies.
Re: simple array question
by eff_i_g (Curate) on Jan 03, 2011 at 04:56 UTC
Re: simple array question
by tw (Acolyte) on Jan 03, 2011 at 03:27 UTC

    if I replace { with [ like so...

    #!/usr/bin/perl use strict; use warnings; my @compass = [ ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] ]; print $compass[0]->[1];

    I get

    ARRAY(0x8cfc10)

    ...I was expecting N

    can someone please explain this

    thanks

      The [] brackets are used to create a list reference. A reference is a scalar ($ sigil), not an array (@ sigil). To understand references, have a look at perlref. You could get it to work by dereferencing the $compass reference, like this:

      #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $compass = [ ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] ]; print Dumper($compass); print $compass->[0][1];

        thanks, also partly answers my question about the difference between { [ (.

        I think i need to do some more reading on this....

      The reason that it didn't work, is that you didn't follow the directions from eyepopslikeamosquito!

      There is a difference between: ( paren , [ square bracket and { curly brace!

      By using "(" you would get an array of arrays. When you add the extra [, you are adding an additional dimension to the structure and getting arrays of arrays of arrays. So you have to throw in an additional de-referencing operator.

      #!/usr/bin/perl use strict; use warnings; my @compass = ( ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] ); my @compassB = ( [ ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"] ], [ ["A", "B", "C"], ["D", "E", "F"] ] ); print $compass[0]->[1]; #prints N print $compassB[0]->[0]->[1]; #prints N print $compassB[1]->[0]->[1]; #prints B my $ref=\@compassB; #added example with reference print $ref->[0]->[0]->[1]; #prints N my $firstAoA = $compassB[0]; print $firstAoA->[0][1]; #prints N
      In a multi-dimensional structure everything is a reference until you get to the last thing which is the actual data.

        thanks Marshall! the code explains the questions i had about the difference between ( and [

        sorry, i just hadn't read eyepopslikeamosquito very helpful reply before posting again...was still trying different things.

Re: simple array question
by Anonymous Monk on Jan 03, 2011 at 15:07 UTC
    The author of the book is obviously demonstrating how to use an array, since he defines @compass with a beginning "@". Arrays are declared with round brackets, so replace the curled brackets with round brackets, and the program will be functional.