in reply to Newbies question: initializing data structure

$hash{"COUNTS"} = [ (1) x $length ];

The parentheses around 1 are needed here (they specify a list). Otherwise you'd get one string "1111111111", because in scalar context the x operator multiplies/concatenates a string.

For your second case:

$hash{"LISTS"} = [ map [], 1..$length ];

( () x $length wouldn't work here)

Replies are listed 'Best First'.
Re^2: Newbies question: initializing data structure
by roibrodo (Sexton) on Jun 02, 2010 at 11:01 UTC
    Thanks! Let me compllicate that just a bit. suppose I would like to construct an array of length $arr_len of such hashes. What do I do?

      You could apply the same technique:

      my @array = map { LISTS => [ map [], 1..$length ] }, 1..$arr_len;


      P.S.: when you play with this, you'll sooner or later encounter curious things like this:

      my @array = map { 'foo' => $_ }, 1..3; # ok my @array = map { $_ => 'foo' }, 1..3; # not ok: 'syntax error at . +.., near "},"'

      This is because Perl has to guess whether the {...} is an anonymous hash or a block (remember, map supports both map EXPR, LIST and map BLOCK LIST syntax).  In order to be sure what is meant, Perl would have to look ahead up until after the corresponding closing curly to see if there's a comma or not, which would disambiguate the interpretation. Perl doesn't do this, because the closing curly could potentially be many lines later... Rather, it expects you to help disambiguate early, like with a unary plus in this case:

      my @array = map +{ $_ => 'foo' }, 1..3; # ok

      (see map for details)

Re^2: Newbies question: initializing data structure
by roibrodo (Sexton) on Jun 02, 2010 at 11:01 UTC
    Thanks! Let me complicate that just a bit. suppose I would like to construct an array of length $arr_len of such hashes. What do I do?

      specifically, I noticed my @arr = {map { }, 1 .. $arr_len} seems to work, rather than my first guess, which was my @arr = [map { }, 1 .. $arr_len].

      But shouldn't we return a array to assign into @arr? hence use square brackets?

        [ ] and { } return an array and a hash reference respectively, i.e. a scalar. That scalar is assigned to the first element of @arr.  If you want to fill the array with the elements created by map, you probably just want

        my @arr = map { }, 1 .. $arr_len;

        or maybe

        my $arrayref = [ map { }, 1 .. $arr_len ];

        As to the former variant, you can also put parentheses around the list (to make it clear it is a list)

        my @arr = ( map { }, 1 .. $arr_len );

        but syntactically they're not required in this case.


        P.S.: with {map { }, 1..$arr_len} you'd run into problems with an odd-number $arr_len, because hashes need to be initialized from key/value pairs... But using anonymous hashes ({}) as hash keys only is of limited use anyway (they'd end up stringified like 'HASH(0x63aa80)') — and probably not what you meant.