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

That's how autovivification currently works. In order to assign the value to the LHS, you need to look what's in $g->{lkj}. To check for the existence of the key, you first need $g to be a hash reference, if it's undef, it autovivifies, else if it's not a hash ref, you get an exception (under strict). There's no need to create the lkj key in $g, as it wasn't used in an lvalue context, but if you tried to access $g->{lkj}{mno} or $g->{lkj}[2] ...

Use

no autovivification;

if you don't want the structures to be created. See autovivification.

($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,

Replies are listed 'Best First'.
Re^6: Array dereference in foreach()
by pme (Monsignor) on Nov 16, 2017 at 12:17 UTC
    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"; }
      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"; }
      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.