BioRod BioRod - 1 month ago 17
Perl Question

Understanding Arrays of Arrays

I'm going through the documentation of perldsc in the section of Array of Arrays and it shows what an Array of Arrays looks like

@AoA = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
);


In the next section on lines 1 - 4 it shows how to generate one

# reading from file
while ( <> ) {
push @AoA, [ split ];
}


I want to learn how to create one. I created a file and had the following contents in it.


John Adam Joe

Rod Fred James

Allison Frank Jean


Then I used the code from the example to create an Array of Arrays

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my @AoA;

while ( <> ) {
push @AoA, [ split ];
}

print Dumper(@AoA);


When I ran the code, the contents of Dumper is

$VAR1 = [
'John',
'Adam',
'Joe'
];
$VAR2 = [
'Rod',
'Fred',
'James'
];
$VAR3 = [
'Allison',
'Frank',
'Jean'
];


As I can see, it printed 3 arrays, I thought it should print an array of arrays.

But I when ran the same code with a small modification

print Dumper(\@AoA);


It printed.

$VAR1 = [
[
'John',
'Adam',
'Joe'
],
[
'Rod',
'Fred',
'James'
],
[
'Allison',
'Frank',
'Jean'
]
];


Which is an Array of Arrays.

Here is my understanding of \@AoA. This is a pointer to the memory location of @AoA. So please clarify why I had to use \@AoA to get the output that is expected?

UPDATE

I think my confusion is clearly explained in perlreftut


One of the most important new features in Perl 5 was the capability to manage complicated data structures like multidimensional arrays and nested hashes. To enable these, Perl 5 introduced a feature called references, and using references is the key to managing complicated, structured data in Perl.

References in Perl are like names for arrays and hashes. They're Perl's private, internal names, so you can be sure they're unambiguous. Unlike "Barack Obama", a reference only refers to one thing, and you always know what it refers to. If you have a reference to an array, you can recover the entire array from it. If you have a reference to a hash, you can recover the entire hash. But the reference is still an easy, compact scalar value.
You can't have a hash whose values are arrays; hash values can only be scalars. We're stuck with that. But a single reference can refer to an entire array, and references are scalars, so you can have a hash of references to arrays, and it'll act a lot like a hash of arrays, and it'll be just as useful as a hash of arrays.

Answer

This is just due to how variables are passed to Perl subroutines.

A sub takes a list of variables, of any length, as its arguments. If you call a sub with an array as the argument, all the array elements get passed in to the sub.

So

my @array = (1,2,3);

foo(@array);

Is no different than this from the sub's perspective:

my $a = 1;
my $b = 2;
my $c = 3;

foo($a,$b,$c);

If you call Dumper() with any array, you will simply get the list of array elements. It won't "see" the array itself unless you pass it in as a reference.