开发者

Perl looping through a hash produces strange value

I'm using Perl to parse the output from objdump. I have the following code:

#!/usr/bin/perl

%count = {};

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

while (($key, $val) = each %count) {
 print "$key $val\n";
}

In the resulting output, most parts are okay like this:

strhib 2
strcc 167
stmlsda 4
swivc 21
ldmlsia 4

But there is one strange line:

HASH(0x8ae2158) 

What's going on here? I expect $1 to be a string, and ++$count开发者_JAVA百科{"$1"} should be perfectly fine.

Thank you.

So the correct code should be:

#!/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";
}


If you had use warnings; you would have seen: "Reference found where even-sized list expected". Instead of

%count = {};

you should have said

my %count;

What you wrote was equivalent to this:

%count = ({} => undef);

That is, you initialized your hash with an empty hashref as a key with no associated value. The hashref stringified to "HASH(0x8ae2158)" (the number may change). To clear out a hash, you use parens () not braces {}. Braces construct a hash reference.

Even short programs like this should start with:

use strict;
use warnings;

The bugs you catch will be your own. :-)

The warnings pragma is preferred to the -w switch because it acts lexically. See What's wrong with -w and $^W in perllexwarn.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜