Reputation: 45
I am trying to make an array of arrays and then reference them.
I make somethign like:
sub foobar
{
my @array;
my $i;
for ($i = 0; $i < 1000; $i=$i+1)
{
my @row;
$row[0] = $i;
$row[1] = foo($bar);
push @array , [@row];
}
return \@array;
}
I can get to the values via:
$array->[x]->[y];
However I don't understand why the second -> is needed. $array->[x] I understand because $array is a reference. But isn't $array->[x] meant to be an array? Why doesn't this work:
my @notarray = $array->[x];
What exactally is not array filled with now? Because it certainly doesn't seem to be an array containing $i , foo($bar)
How would $array->[x]->[y] be different for a reference to an array of references to arrays?
Upvotes: 1
Views: 784
Reputation: 46183
The second ->
isn't needed, actually.
Here's the deal: All Perl array values and hash values must be scalars. That means either a string, number, or array/hash reference (and not a plain old array or hash).
So the first ->
operator dereferences the array and gets at the x'th row. In there is-- not an array, but an array reference. So in order to get to the data in there, you'd theoretically need another ->
operator.
But get this. Perl is smart: It knows that after one array or hash access, if another access happens, the only way this is possible is through an array/hash reference (because your first array/hash access MUST return a scalar)! So you don't need the second arrow after all.
See perldata for more details.
Upvotes: 4
Reputation: 234795
When you
push @array, [@row];
you are pushing a reference to an array. This is necessary because of Perl's rule that arrays are flattened. So $array->[x] is a reference to the row array, not the row array itself. However, between subscripts, the arrow is optional. So $array->[x]->[y]
is exactly the same as $array->[x][y]
(which is exactly the same as ${$array}[x][y]
, etc.)
This is all explained in the Perl reference tutorial
Upvotes: 2