关于"不能将未定义的值用作ARRAY引用"的不一致行为

Mor*_*789 7 perl perl5.16

为什么以下代码:

use strict;
use warnings;
no warnings 'uninitialized';

use Data::Dumper;

my $user;
my @data = @{$user->{ENTERPRISE}}; # Error on this line
print Dumper($user), qq{Done!\n};
Run Code Online (Sandbox Code Playgroud)

抛出错误" Can't use an undefined value as an ARRAY reference",而以下代码:

use strict;
use warnings;
no warnings 'uninitialized';

use Data::Dumper;

my $user;
foreach my $enterprise(@{$user->{ENTERPRISES}}) {
    print qq{Enterprise:}, $enterprise;
}
print Dumper($user), qq{Done!\n};
Run Code Online (Sandbox Code Playgroud)

不抛出任何东西,而是返回:

$VAR1 = {
          'ENTERPRISES' => []
        };
Done!
Run Code Online (Sandbox Code Playgroud)

两者都有违规代码,但只有一个抛出错误.

可能的答案: Perl的自动化?

我在这里走在正确的轨道上吗?感谢您的输入.

ike*_*ami 9

是的,在第二种情况下发生的事情被称为autovivification,它只发生在第二种情况下,因为自动修复只发生在左值[1].

所以

@{ $x } = $y;
Run Code Online (Sandbox Code Playgroud)

手段

@{ $x //= [] } = $y;
Run Code Online (Sandbox Code Playgroud)

$y = @{ $x };
Run Code Online (Sandbox Code Playgroud)

不代表

$y = @{ $x //= [] };
Run Code Online (Sandbox Code Playgroud)

请记住,foreach将其循环变量别名为其迭代的列表的每个元素,因此这些元素将被计算为左值.

perlref中记录了自动生成,您可以通过autovivification pragma 控制自动生成.


  1. 如果最终deferencing后跟一个索引(例如->[]->{}),参考表达本身被评估为一个左值即使索引整体不.这意味着即使不这样做$y = $x->[0];$y = ${ $x }[0];可以自动生成.$x$y = @{ $x };