1

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?

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, for some reason I had come to believe that it was possible to have arrays of arrays, but they are really arrays of references.
2

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

3 Comments

If I am pushing a reference then why is each row still different? Shouldn't they be refering to the same thing?
@kiasectomondo: You're creating a fresh anonymous reference every time. If you just pushed \@array each time (for the same @array) that would refer to the same thing.
@kiasectormondo => The rows would only refer to the same thing if you had declared the @row array outside of the loop, and taken a reference to it via \@row. The [@row] syntax creates a shallow copy of the array, and returns the new reference. In your case, since you are declaring my @row inside the loop, you can just use \@row and it will work fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.