Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

simple array question

by tw (Acolyte)
on Jan 03, 2011 at 03:05 UTC ( #880118=perlquestion: print w/replies, xml ) Need Help??
tw has asked for the wisdom of the Perl Monks concerning the following question:


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 line 4. >Not an ARRAY reference at 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??


Replies are listed 'Best First'.
Re: simple array question
by eyepopslikeamosquito (Chancellor) 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 (Chaplain) 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 (Sage) 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


    ...I was expecting N

    can someone please explain this


      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.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://880118]
Approved by toolic
[james28909]: how can i write a while loop on one line (in a script) something like print "this\n" && print "that" && <DATA> && print the other\n" && next if /this matches/ while <DATA>?
[james28909]: i have tried with && and and and have tried to rearrange the functions as well to no avail

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2018-05-20 18:40 GMT
Find Nodes?
    Voting Booth?