in reply to Re^5: Array dereference in foreach()
in thread Array dereference in foreach()

If $g is autovivified when it is on the right side of equal sign I just don't get why this throws exception.
my $a; my @b = @$a;
and why this one works smoothly
my $a; foreach (@$a) { print "$_\n"; }

Replies are listed 'Best First'.
Re^7: Array dereference in foreach()
by choroba (Cardinal) on Nov 16, 2017 at 12:23 UTC
    Note that $a gets autovivified into [] after for (@$a) -- that's because for creates a special context similar to lvalue (as its list's elements are aliased to the loop variable).

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      What is this "special context similar to lvalue"? Is there any difference to usual lvalue other than not throwing exception in case of array-dereferencing undef?

      However it is not special enough to work smoothly with dereferencing undef as hashref. This one throws exception.

      my $a; foreach (keys %$a) { print "$_\n"; }
        keys doesn't propagate the outer context to its argument.
        #!/usr/bin/perl use strict; use warnings; my $x; 1 for %$x; print $x, "\n"; # HASH(0x26a18cd)

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re^7: Array dereference in foreach()
by haukex (Archbishop) on Nov 16, 2017 at 12:43 UTC
    why this throws exception ... my @b = @$a; ... and why this one works smoothly ... foreach (@$a) { }

    I hope that my earlier explanations, about why my $x; my $y = @$x; throws an error but my $x; @$x = (); does not, make sense? Do you see how in the second example, @$x is in "lvalue context", that is, it is on the left-hand side of the assignment?

    foreach is kind of special, it aliases the loop variable to the things it is looping over. In the following, see how $val becomes an alias for each of the variables in turn and the original values $x,$y,$z are modified via $val:

    my ($x,$y,$z) = ('x','yy','zzz'); for my $val ($x,$y,$z) { $val = $val . length($val); } print "$x/$y/$z\n"; # prints "x1/yy2/zzz3"

    Loosely speaking, this is why the variables foreach (...) is looping over are treated by Perl as if they were on the left-hand side of an assignment (lvalue context), and why the autovivification behavior is applied to them.