shamat has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks, I have a question for you concerning the behavior of exists on hash keys. Please consider this code:
use strict; use warnings; use Data::Dumper; my %hash_data = (); my $key1 = "a"; my $key2 = "1"; my $key3 = "B"; my $key4 = "_"; if (exists $hash_data{$key1}{$key2}{$key3}{$key4}) { print "exists\n"; } else { print "DOES NOT EXIST\n" } print "-----\n"; print Dumper (\%hash_data);
prints:
DOES NOT EXIST ----- $VAR1 = { 'a' => { '1' => { 'B' => {} } } };
It looks like some sub-keys are generated (in this case $k1,$k2,$k3) if they don't exist. How can I avoid that? Thanks for sharing your wisdom!

Replies are listed 'Best First'.
Re: question on hash behavior
by toolic (Bishop) on May 03, 2016 at 16:49 UTC
Re: question on hash behavior
by AnomalousMonk (Archbishop) on May 03, 2016 at 20:18 UTC

    I haven't any real experience with it, but there's also the autovivification pragma. Because I'm not familiar with it, I would tend to use it in the narrowest possible scope:

    c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dump; ;; my %hash; dd \%hash; ;; if (do { no autovivification; exists $hash{foo}{bar}{99}{x}{y} }) { print 'got it'; } ;; dd \%hash; " {} {}
    This also works with statement modifiers, e.g.:
        print 'got it' if do { no autovivification;  exists $hash{foo}{bar}{99}{x}{y} };


    Give a man a fish:  <%-{-{-{-<

Re: question on hash behavior
by BillKSmith (Monsignor) on May 03, 2016 at 18:28 UTC
    if ( exists $hash_data{$key1} and exists $hash_data{$key1}{$key2} and exists $hash_data{$key1}{$key2}{$key3} and exists $hash_data{$key1}{$key2}{$key3}{$key4} ) {
    Bill
Re: question on hash behavior
by perlingRod (Novice) on May 03, 2016 at 17:25 UTC

    The syntax in the if statement is that of a hash of hashes, four deep. Below is what I think you are really trying to do.

    use strict; use warnings; use Data::Dumper; my %hash_data = (); #my $key1 = "a"; #my $key2 = "1"; #my $key3 = "B"; #my $key4 = "_"; my @keys = ("a", "1", "B", "_"); $hash_data{a} = "aValue"; for my $key (@keys) { if (exists $hash_data{$key}) { print "exists\n"; } else { print "DOES NOT EXIST\n" } } print "-----\n"; print Dumper (\%hash_data);
      Thank you all! Autovivification is what I was missing. Today I learned something.