Why does the empty Perl hash have one key?

The standard googleable answer is "How do I know the hash size in Perl?" "takes the size of keys(%hash) ":

 my %h = {}; print scalar (keys (%h)); 

Fingerprint "1". I expected zero. On the other hand. Similarly

 my %h = {}; $h{"a"} = "b"; $h{"x"} = "y"; print scalar keys (%h); print "\nKey: $_" for (keys %h); 

Print

3

Key: a

Key: x

Key: HASH (0x229e8)

Where did this extra meaning come from?

+8
perl key hash size
source share
4 answers

It also came a little.

 my %h = (); 

Note the use of () instead of {} .

Explanation: The value {} is a hash reference, not a hash itself. In Perl, a link is a kind of scalar value, and assigning %h has special handling to assign a single scalar value. It builds a scalar (gives you the HASH(0x229e8) string HASH(0x229e8) in your case) and associates this key with the undef value.

When using () assigning from a list to a hash creates key / value pairs from the pairs in the list, and since () empty, the %h hash becomes empty.

+20
source share
 $ 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.

Better yet, add diagnostics to the mix:

 $ 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 
+24
source share

{} - link to an anonymous hash. So my %h = {} equivalent to my %h = ({} => undef) .

Perl requires the hash keys to be strings, so when you use the link as the key, Perl uses the reference string representation ( HASH(0x229e8) ).

+7
source share
 use Data::Dumper; my %h = {}; warn Dumper \%h; 

%h is assigned as a hash reference as a key and undef as a value.

Output:

 $VAR1 = { 'HASH(0x8683830)' => undef }; 

As rafl suggested, the warnings pragma warnings catch this. See Greg Huglill's response to the revised code.

+6
source share

All Articles