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.
精彩评论