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

I think that the OPs problem is that an array-type variable, @a, is being assigned an array reference, $href.

Sorry, but that's not the right way to look at it. @a is not being assigned a reference, instead, the @{...} dereferences the array reference, and it can be used in place of any normal array (perlref), so in effect my @x = @{...} is like assigning an array to an array.

In your third one-liner example, $a plausibly could be undefined.

I'm not sure what you mean, $a is initially undefined in every example. Autovivification is what is causing both $a to go from being uninitialized to holding a hashref (because it's being dereferenced as such with ->{...}) and $a->{list} to come into existence as a hash entry with a value of [] (empty array ref). The third example does not work because in my @x = @{$a->{list}};, the @{$a->{list}} is not in lvalue context. Personally, I think in this case the autovivification behavior is fairly consistent with DWIM:

Edit: Just moved a sentence so the order makes more sense.

Replies are listed 'Best First'.
Re^4: Array dereference in foreach()
by pme (Monsignor) on Nov 16, 2017 at 09:54 UTC
    Hi haukex,

    Thank you to for your detailed explanation. That makes sense. However I found another interesting feature.

    my $h; my $g; $h->{abc} = $g->{lkj}; print "h: ", Dumper(\$h), "\n"; print "g: ", Dumper(\$g), "\n";
    and the output is
    h: $VAR1 = \{ 'abc' => undef }; g: $VAR1 = \{};
    The left side ($h) is autovivified and undef is assigned to key 'abc'. It is correct. But what has happened on the right? Is it semi-autovivified or what? Empty anonymous hashref is assigned to $g. Where is 'lkj'? Is $g->{lkj} in lvalue context? Why there is no exception?

    Regards

      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,
        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"; }

      Hi, on a side note, you don't need to pass to Data::Dumper a reference to the structure you are dumping, if that structure is already a reference.

      my %hash = ( foo => 'bar' ); my $href = { baz => 'qux' }; print " hash: ", Dumper( \%hash ), "\n"; print "hashref: ", Dumper( $href ), "\n";

      Hope this helps!


      The way forward always starts with a minimal test.