取消引用未定义的数组引用时的 Perl vivification 问题
我很难理解为什么以下内容有效:
my $array_reference;
foreach $element (@{$array_reference}) {
# some code
}
虽然以下内容不起作用,但
my $array_reference;
if (scalar (@{$array_reference}) {
# some code here
}
我理解 perl 带来了生命(自动激活)未定义的引用。但我仍然很困惑为什么后面的代码段会抛出 FATAL 错误。
I'm having tough time in understanding why the following works:
my $array_reference;
foreach $element (@{$array_reference}) {
# some code
}
while the following does not work
my $array_reference;
if (scalar (@{$array_reference}) {
# some code here
}
I understand that perl brings to life (auto-vivifies) undefined reference. But I am still confused as in why the latter code segment throws FATAL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在左值上下文中取消引用 autovivify(意味着当需要可修改的值时),并且 foreach 创建左值上下文。
最后两个创建一个左值上下文,因为它们需要一个值来别名
$_[0]
和$_
(分别)。Dereferences autovivify in lvalue context (meaning when a modifiable value is expected), and foreach create an lvalue context.
The last two create an lvalue context because they need a value to which to alias
$_[0]
and$_
(respectively).Perl 在这方面存在不一致之处,但一般来说,可以修改结构的代码会自动生成,而不会修改结构的代码则不会。如果它不自动激活,它会尝试取消引用未定义的值,这会触发警告,或者在
使用严格的“refs”
下触发异常。Perl has inconsistencies in this area, but in general, code that may modify a structure autovivifies, while code that won't doesn't. And if it doesn't autovivify, it is trying to dereference an undefined value, which triggers a warning, or, under
use strict "refs"
, an exception.我认为,查看perlref,这是预期的行为:
“适当的参考如果您在假定它们存在的上下文中取消引用它们,则类型可以突然出现。”
与 foreach 类似的情况也发生在 Push() 和朋友身上:
尽管不是新的 can-just-take-a-reference版本:
有效,同时
有效不,我认为这是明智的,因为 Push 不知道你真正的意思是什么。
有趣的问题是 scalar(@$undef) 应该做同样的事情,还是应该发出警告,因为它最终返回 undef,我认为它最好立即发出警告。
I think, looking at perlref, that this is expected behaviour:
"References of the appropriate type can spring into existence if you dereference them in a context that assumes they exist."
A similar thing to foreach happens with push() and friends:
Although not with the new, can-just-take-a-reference versions:
works, while
does not, which I think is sensible as push has no idea what you really meant there.
The interesting question is should scalar(@$undef) do the same thing, or should warn, as it eventually returns undef, I think it might as well warn right away.