Perl循环遍历哈希会产生奇怪的值

Rya*_* Li 3 perl

我正在使用Perl来解析输出objdump.我有以下代码:

#!/usr/bin/perl

%count = {};

while (<>) {
 if (/^\s+[[:xdigit:]]+:\s+[[:xdigit:]]+\s+([a-z]+).+$/) {
  ++$count{"$1"};
 }
}

while (($key, $val) = each %count) {
 print "$key $val\n";
}
Run Code Online (Sandbox Code Playgroud)

在结果输出中,大多数部分都可以这样:

strhib 2
strcc 167
stmlsda 4
swivc 21
ldmlsia 4
Run Code Online (Sandbox Code Playgroud)

但有一条奇怪的路线:

HASH(0x8ae2158) 
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?我期待$1成为一个字符串,++$count{"$1"}应该是完美的.

谢谢.

所以正确的代码应该是:

#!/usr/bin/perl

use strict;

my %count;

while (<>) {
 if (/^\s+[[:xdigit:]]+:\s+[[:xdigit:]]+\s+([a-z]+).+$/) {
  ++$count{"$1"};
 }
}

while (my ($key, $val) = each %count) {
 print "$key $val\n";
}
Run Code Online (Sandbox Code Playgroud)

cjm*_*cjm 8

如果你有,use warnings;你会看到:"参考找到了预期的偶数大小的列表".代替

%count = {};
Run Code Online (Sandbox Code Playgroud)

你应该说的

my %count;
Run Code Online (Sandbox Code Playgroud)

你写的东西等同于:

%count = ({} => undef);
Run Code Online (Sandbox Code Playgroud)

也就是说,您使用空hashref初始化哈希作为没有关联值的键.hashref字符串化为"HASH(0x8ae2158)"(数字可能会改变).要清除散列,请使用parens ()而不是大括号{}.大括号构造一个哈希引用.

即使这样的短程序也应该从以下开始:

use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)

你捕获的bug将是你自己的.:-)

警告附注优选将-w开关,因为它充当词法.见出了什么问题-w,并$^Wperllexwarn.

  • `use warnings`更有用,因为它是词法范围的(所以你可以在块级别关闭它,当你需要做其他警告生成的事情).但是`-w`对于单行来说肯定是好的. (4认同)
  • `use strict`(虽然一个好主意)不会捕获这个特殊的错误.但是"使用警告"会. (3认同)