Perl: while ($key = every %hash) 不会在 key = 0 处停止
显然我不需要这个; 我只是好奇这里发生了什么。 我失踪了吗 简单的事情吗? 我可以在所有版本的 Perl 中依赖此行为吗?)
Perl v5.8.8:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
while ($k = each %h) {
$v = delete $h{$k};
print "deleted $v; remaining: @h{0..2}\n";
}
输出
deleted one; remaining: zero two
deleted zero; remaining: two
deleted two; remaining:
man perlfunc
(each) 没有解释为什么 当 $k
被赋值为 0 时,while 循环继续。 该代码的行为就像 while
循环中的条件一样 为($k = 每个%h,已定义$k)
。
如果循环条件实际上改为 ($k = every %h, $k)
那么它确实 按预期停在 $k = 0
处。
对于以下情况,它也会在 $k = 0
处停止 重新实现 each
:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
sub each2 {
return each %{$_[0]};
}
while ($k = each2 \%h) {
$v = delete $h{$k};
print "deleted $v; remaining: @h{0..2}\n";
}
输出:
deleted one; remaining: zero two
I don't need this, obviously; I'm just curious about what's going on here. Am I missing
something simple? Can I rely on this behaviour in all versions of Perl?)
Perl v5.8.8:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
while ($k = each %h) {
$v = delete $h{$k};
print "deleted $v; remaining: @h{0..2}\n";
}
outputs
deleted one; remaining: zero two
deleted zero; remaining: two
deleted two; remaining:
man perlfunc
(each) does not explain why the
while loop continues when $k
is assigned 0.
The code behaves as if the condition on the while
loop
were ($k = each %h, defined $k)
.
If the loop condition is actually changed to($k = each %h, $k)
then it does indeed
stop at $k = 0
as expected.
It also stops at $k = 0
for the following
reimplementation of each
:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
sub each2 {
return each %{$_[0]};
}
while ($k = each2 \%h) {
$v = delete $h{$k};
print "deleted $v; remaining: @h{0..2}\n";
}
outputs just:
deleted one; remaining: zero two
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在标量上下文中调用
each
,因此由于列表返回值而无法正常工作。就像
特殊情况下添加隐式
定义
一样,在 5.8.8 中,发生在 op.c,第 3760-3766 行中:
我不确定这是否适用于所有版本Perl 5。
另请参阅:PerlMonks 上 while() 何时测试定义与真实。 我找不到 Perl 文档中提到的地方(提到了
情况,但我没有看到each
情况)。You're calling
each
in scalar context, so it's not working because of a list return value.Just like
is special-cased to add an implicit
defined
, so isIn 5.8.8, that happens in op.c, lines 3760-3766:
I'm not sure if this applies to all versions of Perl 5.
See also: When does while() test for defined vs truth on PerlMonks. I can't find where this is mentioned in the Perl docs (the
<FILE>
case is mentioned, but I don't see theeach
case).cjm是对的。 我只是想补充一点,当遇到这样的奇怪事情时,通过 B::Deparse 看看 Perl 如何理解你的代码。 我也喜欢使用 -p 开关来显示优先级错误。
cjm is right. I just want to add that when coming up against strange things like this its often helpful to run your code through B::Deparse to see how Perl understood your code. I like to use the -p switch to show precedence mistakes, too.
谢谢,cjm。
很明显,某种
定义的隐式添加
glob 的情况是这样的,但不是在哪里
记录在案。 现在至少我知道有限的情况
特殊处理适用。
但这些信息应该在 perlfunc 文档中,
不仅仅是 Perl 源代码!
Thanks, cjm.
It was clear some kind of implicit addition of a
defined
was going on like that for glob but not where it was
documented. Now at least I know the limited cases in which
that special handling applies.
But the information should be in the perlfunc documentation,
not just the Perl source code!