Fabricating hash keys

125 views Asked by At

I have inexplicable behavior in which Perl is fabricating a "null" hash key out of thin air. I'm simply grabbing keys from an existing hash and creating a new hash with the same keys. Despite there being only 15 keys in the original hash, the newly formed one has gained a mysterious 16th key.

Here is the relevant code:

DO_SOMETHING(\%Hash1, \%Hash2);

sub DO_SOMETHING {
    my %Hash3 = undef;
    my $count = 0;                                       # reset counter
    my ($Hash1Ref, $Hash2Ref) = @_;                      # grab arguments to subroutine
    my %Hash1 = %$Hash1Ref;                              # dereference hash #1
    my %Hash2 = %$Hash2Ref;                              # dereference hash #1
    my @Hash2keys = sort {$a <=> $b} keys %Hash2;        # grab keys from Hash #2
    print "Hash #2 keys = ", join (',', @Hash2keys), "\n"; # print keys in Hash # 2
    my $NumHash2keys = @Hash2keys;
    print "Number of Hash #2 keys = $NumHash2keys\n";    # print number of keys in Hash #2
    print "Building new hash (Hash #3) using keys from Hash #2\n";
    foreach my $Hash2key (@Hash2keys) {                  # iterate through Hash # 2 keys
      $count ++;                                         # count number of iterations
      $Hash3{$Hash2key} = 1                              # mirror keys from Hash #2 in a new hash (Hash #3)
    }   
  
    print "Number of Hash #2 key iterations = $count\n"; # confirm number of iterations through Hash #2 keys
    my @Hash3keys = keys %Hash3;
    print "Hash #3 keys = ", join (',', @Hash3keys), "\n";
    my $NumHash3keys = @Hash3keys;
    print "Number of Hash #3 keys = $NumHash3keys\n";
}

And here is the output:

Hash #2 keys = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
Number of Hash #2 keys = 15
Building new hash (Hash #3) using keys from Hash #2
Number of Hash #2 key iterations = 15
Hash #3 keys = 1,10,4,12,3,13,6,2,15,14,7,,11,9,8,5
Number of Hash #3 keys = 16

I can't for the life of me figure out where the 16th "null" key is coming from. It appears to be assigned during an invisible loop.

2

There are 2 answers

0
toolic On

Don't initialize %Hash3 with undef.

Change:

my %Hash3 = undef;

to:

my %Hash3;

If you add the following line to the top of your code (which you should always do), you will get a warning message:

use warnings;
0
Tiago Peczenyj On

Your issue is the initialization of %Hash3.

You don’t need to set to anything.

The undef make sense for references, not for hashes or arrays

Try this example

my %foo = undef;
use Data::Dumper;
print(Dumper(\%foo));

Output:

 $VAR1 = {
      '' => undef
    };

What happens, this;

my %foo = undef;

Is the equivalent to

my %foo = "" => nothing/ undefined since you don’t specify it

And since hashes force the stringfication of the key, the undefined value returned by function undef became empty string.

try add in the beginning of your code:

use strict;
use warnings;

Probably will help to catch some mistakes, for instance:

Odd  number of elements in hash assignment at main.pl line X.
Use of uninitialized value in list assignment at main.pl line X.