Dear brothers in this Monastery

It has been brought to my attention this behavior:

% perl -MData::Dumper $c->[3] = 3; print Dumper( $c ); for ( @$c ) { $_++ } print Dumper( $c ); __END__ $VAR1 = [ undef, undef, undef, 3 ]; $VAR1 = [ 1, 1, 1, 4 ];

However, this code, crashes:

% perl -MData::Dumper $c->[3] = 3; print Dumper( $c ); map { $_++ } @$c; print Dumper( $c ); __END__ $VAR1 = [ undef, undef, undef, 3 ]; Modification of a read-only value attempted at - line 3.

Changing the above code for: map { $_++ if defined $_ } @$c yields the correct result of 3 undefs and 4 (with 4 changes, because map processed 4 elements nevertheless). And we get the same result if we test the definedness of $_ in the for loop. This happens as well working directly with the array (instead of a reference) and as well inside a hash, etc...

I interpret this is happening: for (in the lack of a lexical or otherwise explicit variable before the array comes) aliases $_ for the local BLOCK with each value of the array, as they come. On the other hand, map expects an EXPR or a BLOCK to act, aliasing $_ inside the BLOCK or EXPR to each member of the array, one at a time as they come from the array.

Now, in the first case exposed (for), for some reason, the undefs in the array are first converted to 0, then we increment them. In the case of map, we are trying to increment an undef, which is not possible.

'diagnostics' is not very helpful in this case, and the examples offered as a possible source of the error actually talk about a for loop, not a map.

Of course, if Perl had real sparce arrays (as we are likely to get for Perl 6) this would probably be a different can of worms, as we would be still facing the problem of what to do with those array elements not yet initialized.

I ask to the monks of this noble Monastery: is this the expected behavior of map and for in this case, or are we facing an ugly bug?

Most grateful,

--
our $Perl6 is Fantastic;


In reply to "Sparse" Array behavior with "for" and "map" by Excalibor

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.