我很难理解为什么以下工作:
my $array_reference;
foreach $element (@{$array_reference}) {
# some code
}
而以下不起作用
my $array_reference;
if (scalar (@{$array_reference}) {
# some code here
}
我知道 perl 带来了生命(自动激活)未定义的引用。但是我仍然对为什么后一个代码段会抛出 FATAL 感到困惑。
我很难理解为什么以下工作:
my $array_reference;
foreach $element (@{$array_reference}) {
# some code
}
而以下不起作用
my $array_reference;
if (scalar (@{$array_reference}) {
# some code here
}
我知道 perl 带来了生命(自动激活)未定义的引用。但是我仍然对为什么后一个代码段会抛出 FATAL 感到困惑。
在左值上下文中取消引用 autovivify(意味着当期望一个可修改的值时),并且 foreach 创建一个左值上下文。
>perl -E"$$x = 1; say $x;"
SCALAR(0x74b024)
>perl -E"++$$x; say $x;"
SCALAR(0x2eb024)
>perl -E"\$$x; say $x;"
SCALAR(0x30b024)
>perl -E"sub {}->($$x); say $x;"
SCALAR(0x27b03c)
>perl -E"for ($$x) {} say $x;"
SCALAR(0x25b03c)
最后两个创建一个左值上下文,因为它们需要一个值来别名$_[0]
和$_
(分别)。
Perl 在这方面有不一致的地方,但一般来说,可能修改结构的代码会自动激活,而不会修改的代码不会。如果它不自动激活,它会尝试取消引用一个未定义的值,这会触发一个警告,或者,在 下use strict "refs"
,一个异常。
我认为,看着perlref,这是预期的行为:
"如果您在假定它们存在的上下文中取消引用它们,那么适当类型的引用就会出现。 "
与 foreach 类似的事情发生在 push() 和朋友身上:
my $f;
push @$f, 1;
say @$f;
虽然不是新的,可以只是参考的版本:
my $f = [];
push $f, 1;
say @$f;
工作,而
my $f;
push $f, 1;
say @$f;
没有,我认为这是明智的,因为 push 不知道你在那里的真正意思。
有趣的问题是 scalar(@$undef) 应该做同样的事情,还是应该发出警告,因为它最终会返回 undef,我认为它不妨立即发出警告。