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

I'm reading a book on Perl and see:
@list_of_lists = ( [ qw( Mustang Bronco Ranger ) ], [ qw( Cavalier Suburban Buick ) ], [ qw( Lebaron Ram ) ], );
Are the elements in the @list_of_lists anonymous array references?

Replies are listed 'Best First'.
Re: Anonymous Reference???
by halley (Prior) on Sep 12, 2005 at 03:50 UTC
    Yes.

    An array can ONLY contain scalar elements. A reference to an array IS a scalar, so that's how you get arrays of arrays.

    my @a = ( 1, 2, 3 ); # make an array my $ra = \@a; # make a reference to @a my $rb = [ 4, 5, 6 ]; # make a reference to an anonymous arra +y my @aoa = ( $ra, $rb ); # make an array of arrays
    You then can fetch $aoa[1][1] and get 5.

    perldoc: perllol, perlreftut, perlref, etc. Also try Data::Dumper for ideas on how to visualize structures in Perl syntax.

    --
    [ e d @ h a l l e y . c c ]

      "An array can ONLY contain scalar elements."

      Strictly speaking, you were not 100% correct as the following code is valid:

      use Data::Dumper; use strict; use warnings; my @a = ((1,2,3), (4,5,6)); print $a[3];

      So array can contain array. However Perl "flattens" the inner arrays, and does not remember the boundary information. This made it impossible to use this way to represent multi-dimentional array, and the array of array ref comes to rescue.

      Update: Yes, the example sk given in his reply demos my point better.

      However I disagree with his conclusion. I don't think either side is really wrong, and it really depends on whether you look at it from a syntax point of view (my view) or an internal represent view.

        This is incorrect. In this code:

        my @a = ((1,2,3), (4,5,6));

        ... there is only one array: @a. Everything else is a list. Lists are not arrays; lists and arrays behave very differently in various contexts, for example.

        The parentheses in the expression are for grouping to change the precedence of the right-side of the assignment, not to create lists (and especially not to create arrays).

        pg writes: I don't think either side is really wrong, and it really depends on whether you look at it from a syntax point of view (my view) or an internal represent view.

        Syntax is only useful insofar as it develops a data structure. Data structures are what enable algorithms. Following all of perl's "there is more than one way to phrase it" syntax eccentricities will just confuse you; conversely, recognizing perl's very few, very simple, very self-consistent data structures will let you accomplish many algorithms with few errors borne of such confusion.

        • a scalar is O(1) in storage; undef, int, real, string, or reference;
          sometimes there are cached alternative representations but it's still O(1)
        • an array contains a known number, zero or more, of scalars
        • a hash associates zero or more pairs; each pair is a unique string key and an arbitrary scalar value
        • (globs are public implementation details of the machine, skipped for this discussion)

        Lists have no name and no known length. You can't take $#list or $list[-1] or even $list[3] without a conversion to array first. Lists are not a first-class storage data structure, but are the product of processing the syntax of literals, or the product of iteration.

        --
        [ e d @ h a l l e y . c c ]

Re: Anonymous Reference???
by davidrw (Prior) on Sep 12, 2005 at 03:52 UTC
    yes -- that's creating a 2-D array.. When in doubt of what a data structure contains, a easy way to look at it is to just use Data::Dumper like this:
    use Data::Dumper; print Dumper \@list_of_lists; __END__ OUTPUT: $VAR1 = [ [ 'Mustang', 'Bronco', 'Ranger' ], [ 'Cavalier', 'Suburban', 'Buick' ], [ 'Lebaron', 'Ram' ] ];
    quick side note -- example of accessing that structure:
    print $list_of_lists[1]->[2]; # Buick
Re: Anonymous Reference???
by Thilosophy (Curate) on Sep 12, 2005 at 03:50 UTC
    Yes, they are.
    my $r = [ 1 , 2, 3]; # arrayref my $q = { 1 =>2 , 3=> 4 }; # hashref my $t = sub{ print 1; }; # code ref