If you use a hash slice in lvalue context, Perl must create the elements of the slice in case they will actually be modified.

>perl -E"1 for @h{x}; say exists($h{x}) || 0; 1 >perl -E"sub {}->( @h{x} ); say exists($h{x}) || 0; 1 >perl -E"my $r = \@h{x}; say exists($h{x}) || 0; 1

The for loop might assign to $_ with the intention of changing $h{x}, so a copy can't be used.

The sub might assign to $_[0] with the intention of changing $h{x}, so a copy can't be used.

$$r must refer to $h{x}, so a copy can't be used.

As for join, it's a builtin operator (just like ("+"), not a sub call. Perl knows it doesn't need for lvalues, so it provide any. That's not the case for subs, though. Perl has no idea if the sub will pass values back by reference, so it much create lvalues just in case.

Sidebar

One exception!

>perl -E"1 for $h{x}; say exists($h{x}) || 0; 1 >perl -E"sub {}->( $h{x} ); say exists($h{x}) || 0; 0 >perl -E"\@h{x}; say exists($h{x}) || 0; 1

When a hash element (not a hash slice) is used as a sub argument, a special magical value is returned. Assigning to that magical value assigns to the hash. Getting a reference to magical value gets a reference to the hash element. Both of these cause the element's vivification, but not before. It's a bit slower to create and use this magical value, but it prevents a lot of accidental hash key vivifications.

The special magical value isn't returned for other lvalue contexts, and hash slices aren't coded to ever return these magical values.

To avoid vivification of the hash elements, you must avoid using the hash slice in lvalue context. You can do that by making copies of the values returned by the slice.

>perl -E"sub {}->( @{[ @h{x} ]} ); say exists($h{x}) || 0;" 0 >perl -E"sub {}->( do { @h{x} } ); say exists($h{x}) || 0;" 0

etc.


In reply to Re: Autovivification and hash slices by ikegami
in thread Autovivification and hash slices by norbert.csongradi

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.