Question

I am using a hash table in my code

my %stat = ();
# read files and do some initialization 
# like  $stat{$key} = {k1=>v1, k2=>v2, k3=>v3};
#   I have located the buggy code
# I want to do something according to c1 and c2 parsed from each line of the file
if(!exists $stat{c1}) {   # I thought I would have initialized all possible used keys here, but it is not true as seen below
    $stat{c1} = {k1=>0, k2=>0, k3=>0};
} 
if( $c1 == $c2) {
    $stat{c1}{k1}++;
} else {
    $stat{c1}{k2}++;
    $stat{c2}{k3}++;  #Note: I forgot to check whether $stat{c2} has been initialized here!
}



map {
    my $val = $stat{$_}{k1};  
    print "$val\n";     # run time error shows "use of uninitalized $val"
} keys %stat;

I wrote some print statement to debug the program. I found out that some key value mysteriously appears in the hash table "%stat", despite that I've never insert it! Say $stat{510} somehow exists despite that I never insert it, but its value (a hash table reference in my case) was not initialized. I have to write a statement:

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

to remove the unwanted keys.

Can you tell me why some mysterious key can appear from (keys %stat)?

Thanks, Jeff

Was it helpful?

Solution

Can you tell me why some mysterious key can appear from (keys %stat)?

Because the code you did not show somehow created them.

Perhaps you did $stat{510}{k1}? Keep in mind that

$stat{510}{k1}

is short for

$stat{510}->{k1}

and

$x->{...}

does

( $x //= {} )->{...}

so

$stat{510}{k1}

does

( $stat{510} //= {} )->{k1}

Notice how this assigns to $stat{510}?


Using map as a for loop is frowned upon.

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

is better written as

delete $stat{$_} for grep !defined($stat{$_}{k1}), keys %stat;

or even

delete @stat{ grep !defined($stat{$_}{k1}), keys %stat };

OTHER TIPS

Because of the autovivification. It means that when you refer to a hash entry, it is created without complaint. And if you don't assign a value at that time, it is initialized with a value of undefined. So in the part of your code where you have

##read files and do some initialization 

make sure that you are not reading or writing an entry with key 510.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top