3
use strict;                  
use warnings FATAL => 'all'; 

my $x = undef;               
if (@$x) { print "ok\n" }    
else { print "no\n" } 

Predictably yields "Can't use an undefined value as an ARRAY reference" for if (@$x). But inserting a foreach (@$x):

use strict;                  
use warnings FATAL => 'all'; 

my $x = undef;               
foreach (@$x) { print $_ }  # <------- 
if (@$x) { print "ok\n" }    
else { print "no\n" }        

print ref($x)."\n"; 

Outputs:

no
ARRAY

The foreach line seems to have made an assignment to $x. What's up with this?

CodeClown42
  • 11,194
  • 1
  • 32
  • 67
  • 1
    Possible duplicate of [Why does Perl autovivify in this case?](https://stackoverflow.com/questions/2206836/why-does-perl-autovivify-in-this-case) – pilcrow Jun 26 '19 at 16:12

1 Answers1

3

Autovivification makes

@$x

equivalent to

@{ $x //= [] }

in lvalue context.

Use

if ($x) {
   for (@$x) {
      ...
   }
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • The question (as I understand it) was why is `for` an lvalue context. – choroba Jun 26 '19 at 16:06
  • 1
    @choroba, I don't think so (because it's a warning in rvalue context, and there's no mention of rvalue context. But just in case, the following is the answer to that: Because the loop body could assign to the loop iterator and change the values. (e.g. `for (@a) { $_ = uc($_); }`) – ikegami Jun 26 '19 at 16:08
  • 2
    I know, just trying to help make the answer more informative :-) – choroba Jun 26 '19 at 16:10