Perl 不一致的行为涉及;Can';t使用未定义的值作为数组引用";
为什么会出现以下代码:Perl 不一致的行为涉及;Can';t使用未定义的值作为数组引用";,perl,perl5.16,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}; use strict; use warnings; no warnings 'uninitialized'; use
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};
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};
抛出错误“不能将未定义的值用作数组引用”
,而以下代码:
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};
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};
不会抛出任何内容,而是返回:
$VAR1 = {
'ENTERPRISES' => []
};
Done!
两者都有令人不快的代码,但只有一个抛出了错误
可能的答案:
我走对了吗?感谢您的输入。是的,在第二种情况下发生的情况称为自动活体化,并且只在第二种情况下发生,因为自动活体化只对左值发生[1] 所以 意味着 但是 这并不意味着
$y = @{ $x //= [] };
请记住,foreach将其循环变量别名为它迭代的列表中的每个元素,因此这些元素将作为左值进行计算
自动活体记录在中,您可以通过pragma控制自动活体
->[]
或->{}
),则引用表达式本身将作为左值进行计算,即使索引的整体不是左值。这意味着$y=$x->[0]
和$y=${$x}[0]
可以自动激活$x
,即使$y=@{$x}代码>不会
你到底想做什么?事实上,您已经关闭了警告,这应该是一个很好的警告,说明这不是一个好主意。第一个代码块来自抛出错误的旧代码,必须修复,而第二个代码块是我担心也需要修复的新代码,但我想不会,因为它没有抛出我在过去看到的错误。这是非常有用的。关于foreach如何工作的最后一点是,通过对循环变量进行别名,使我们处于左值状态,这确实澄清了问题。左值/右值的区别是否有正式记录在案?@Morrowind789在第3点“使用引用”下简要提到了它。同样根据中的自活定义。自活文档(in)中有:“这是我们前面提到的一种情况,在左值上下文中引用可能会出现。[…]此过程称为自活。”此外,您可以通过添加
无自活qw(存储)来防止这种行为
到您的脚本。“它只发生在第二种情况下,因为它只发生在左值上。”它也发生在右值上,但被严格的“refs”禁止,对吗<代码>perl-E'$a=$b->{c};说ref($b)
$y = @{ $x //= [] };