tags:

views:

309

answers:

3

How do I initialize a 2d array in perl?

I am trying the following code:

 0 use strict;
10 my @frame_events = (((1) x 10), ((1) x 10));
20 print "$frame_events[1][1]\n";

but it gives the following error:

Can't use string ("1") as an ARRAY ref while "strict refs" in use at ./dyn_pf.pl line 20.

This syntax only seems to initialize a 1d array as print "$frame_events[1]\n" works. Though perl doesn't give any error during the assignment.

+6  A: 

You cannot have an array of arrays in Perl, only an array of references to arrays.

my @frame_events = ([(1) x 10], [(1) x 10]);
print "$frame_events[1]->[1]\n";

Special case: you are free to omit the pointer dereferencing arrow between adjacent brackets (whether square or curly):

print "$frame_events[1][1]\n";

In general you cannot have:

  • arrays of arrays (of arrays ...)
  • arrays of hashes (of ...)
  • hashes of arrays
  • hashes of hashes.

You can have:

  • arrays of references to arrays (of references to arrays ...)
  • arrays of references to hashes (of references to ...)
  • hashes of references to arrays
  • hashes of references to hashes

You can also have:

  • arrays of scalars
  • arrays of references of arrays of scalars
  • arrays of references of arrays of references of arrays of scalars
  • arrays of references of hashes of scalars
  • etc.

Cheers, V.

vladr
Note that this doesn't stop people from saying "hash of hashes", "array of hashes", etc. in everyday conversation, because it's *understood* that every value in a hash or an array is a scalar, so we all know we're talking about references.
hobbs
+6  A: 

See also Array of Arrays in Perl Data Structures Cookbook.

Sinan Ünür
A: 

In Perl an array with two arrays in it get merged into a single array. You want references for the internal arrays if you don't want them concatenated. Here's a dump of your code:

use strict;
use Data::Dumper;
my @frame_events = (((1) x 10), ((1) x 10));
print Dumper(\@frame_events);

result:

$VAR1 = [
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1,
          1
        ];

and if you switch to array reference creators, brackets instead of parents, with this code:

use strict;
use Data::Dumper;
my @frame_events = ([(1) x 10], [(1) x 10]);
print Dumper(\@frame_events);

you get this:

$VAR1 = [
          [
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1
          ],
          [
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1
          ]
        ];
Ry4an
"In Perl an array with two arrays in it get merged into a single array" -- inaccurate. *Lists* get *flattened*. There are no arrays here. :)
hobbs
@Mark: Give a fish to a man, You will feed him for today. Teach man fishery, You will feed him for rest of life. Ry4n given fish to you. Vlad Romascanu and Sinan Ünür are trying teach you fishery.
Hynek -Pichi- Vychodil