The standard googleable answer to "How do I find out the size of a hash in Perl?" is "take the size of keys(%hash)
":
my %h = {};
print scalar (keys (%h));
This prints '1'. I was expecting zero. On the other hand. Similarly,
my %h = {};
$h{"a"} = "b";
$h{"x"} = "y";
print scalar keys (%h);
print "\nKey: $_" for (keys %h);
Prints:
3
Key: a
Key: x
Key: HASH(0x229e8)
Where has this extra value come from?
$ perl -Mwarnings -e'my %h = {}'
Reference found where even-sized list expected at -e line 1.
strict and warnings are included with Perl for very good reasons. There is no reason not to use them.
Even better, add diagnostics into the mix too:
$ perl -Mwarnings -Mdiagnostics -e'my %h = {}'
Reference found where even-sized list expected at -e line 1 (#1)
(W misc) You gave a single reference where Perl was expecting a list
with an even number of elements (for assignment to a hash). This usually
means that you used the anon hash constructor when you meant to use
parens. In any case, a hash requires key/value pairs.
%hash = { one => 1, two => 2, }; # WRONG
%hash = [ qw/ an anon array / ]; # WRONG
%hash = ( one => 1, two => 2, ); # right
%hash = qw( one 1 two 2 ); # also fine
This has bit me before too.
my %h = ();
Note the use of ()
instead of {}
.
Explanation: The value {}
is a reference to a hash, rather than a hash itself. In Perl, a reference is a kind of scalar value, and the assignment to %h
has special processing for assigning a single scalar value. It stringifies the scalar (giving you the string HASH(0x229e8)
in your case), and associates that key with the value undef
.
When using ()
, the assignment from list to hash creates key/value pairs from pairs in the list, and since ()
is empty, the hash %h
becomes empty.
{}
is a reference to an anonymous hash. So my %h = {}
is equivalent to my %h = ({} => undef)
.
Perl requires hash keys to be strings, so when you use a reference as a key, Perl uses the reference's string representation (HASH(0x229e8)
).
use Data::Dumper;
my %h = {};
warn Dumper \%h;
%h
gets assigned with a hash reference as the key and undef
as the value.
Output:
$VAR1 = {
'HASH(0x8683830)' => undef
};
As rafl suggested, the warnings
pragma would have caught this.
Look at Greg Hewgill's answer for the corrected code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With