取消引用未定义的数组引用时的 Perl vivification 问题

发布于 2024-11-16 21:00:07 字数 315 浏览 3 评论 0原文

我很难理解为什么以下内容有效:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

与酒说心事 2024-11-23 21:00:07

在左值上下文中取消引用 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]$_ (分别)。

Dereferences autovivify in lvalue context (meaning when a modifiable value is expected), and foreach create an lvalue context.

>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)

The last two create an lvalue context because they need a value to which to alias $_[0] and $_ (respectively).

神回复 2024-11-23 21:00:07

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.

拧巴小姐 2024-11-23 21:00:07

我认为,查看perlref,这是预期的行为:

适当的参考如果您在假定它们存在的上下文中取消引用它们,则类型可以突然出现。

与 foreach 类似的情况也发生在 Push() 和朋友身上:

my $f;
push @$f, 1;
say @$f;

尽管不是新的 can-just-take-a-reference版本:

my $f = [];
push $f, 1;
say @$f;

有效,同时

my $f;
push $f, 1;
say @$f;

有效不,我认为这是明智的,因为 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:

my $f;
push @$f, 1;
say @$f;

Although not with the new, can-just-take-a-reference versions:

my $f = [];
push $f, 1;
say @$f;

works, while

my $f;
push $f, 1;
say @$f;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文