Perl:while ($key = each %hash) 不会在 key = 0 处停止
Posted
技术标签:
【中文标题】Perl:while ($key = each %hash) 不会在 key = 0 处停止【英文标题】:Perl: while ($key = each %hash) doesn't stop at key = 0 【发布时间】:2010-09-18 06:21:31 【问题描述】:显然,我不需要这个;我只是好奇这里发生了什么。我失踪了吗 简单的东西?我可以在所有版本的 Perl 中依赖这种行为吗?)
Perl v5.8.8:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
while ($k = each %h)
$v = delete $h$k;
print "deleted $v; remaining: @h0..2\n";
输出
deleted one; remaining: zero two
deleted zero; remaining: two
deleted two; remaining:
man perlfunc
(每个)没有解释为什么
当 $k
被赋值为 0 时,while 循环继续。
代码的行为就像while
循环中的条件一样
是($k = each %h, defined $k)
。
如果循环条件实际改为
($k = each %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: @h0..2\n";
只输出:
deleted one; remaining: zero two
【问题讨论】:
【参考方案1】:您在标量上下文中调用each
,因此由于列表返回值而无法正常工作。
就像
while ($line = <FILE>)
是特殊情况下添加隐式defined
,所以是
while ($key = each %hash)
在 5.8.8 中,这发生在 op.c,第 3760-3766 行:
case OP_SASSIGN:
if (k1->op_type == OP_READDIR
|| k1->op_type == OP_GLOB
|| (k1->op_type == OP_NULL && k1->op_targ == OP_GLOB)
|| k1->op_type == OP_EACH)
expr = newUNOP(OP_DEFINED, 0, expr);
break;
我不确定这是否适用于所有版本的 Perl 5。
另见:When does while() test for defined vs truth 在 PerlMonks 上。我找不到 Perl 文档中提到的地方(提到了 <FILE>
案例,但我没有看到 each
案例)。
【讨论】:
【参考方案2】:cjm 是对的。我只想补充一点,当遇到类似这样的奇怪事情时,通过B::Deparse 运行您的代码以了解 Perl 如何理解您的代码通常很有帮助。我也喜欢使用 -p 开关来显示优先级错误。
$ perl -MO=Deparse,p your_example.plx
(%h) = (0, 'zero', 1, 'one', 2, 'two');
while (defined($k = each %h))
$v = delete $h$k;
print "deleted $v; remaining: @h0..2\n";
your_example.plx syntax OK
【讨论】:
【参考方案3】:谢谢,cjm。
很明显,某种隐式添加了 defined
对于 glob 来说就是这样,但不是在哪里
记录在案。现在至少我知道在有限的情况下
该特殊处理适用。
但是信息应该在 perlfunc 文档中, 不仅仅是 Perl 源代码!
【讨论】:
以上是关于Perl:while ($key = each %hash) 不会在 key = 0 处停止的主要内容,如果未能解决你的问题,请参考以下文章