http://www.perlmonks.org?node_id=1018752


in reply to Checking if hash value exists without implicitly defining it

One option is to short circuit the autovivification:

use strict; use warnings; my %Hash; $Hash{44.52}{param1}{key1} = [ 101.01, 'val1' ]; $Hash{95.01}{param2}{key2} = [ 101.02, 'val2' ]; my $neededVal = 80.0; if ( exists $Hash{$neededVal} and exists $Hash{$neededVal}{param1} and exists $Hash{$neededVal}{param1}{key1} ) { print "DEFINED"; } else { for ( keys %Hash ) { print "$_\n"; } }

Output:

95.01 44.52

Update I: Added the needed defined, in case of an earlier (for example) $Hash{$neededVal}{param1}{key1} = 0.

Update II: Replaced defined with exists. Thank you, choroba.

Replies are listed 'Best First'.
Re^2: Checking if hash value exists without implicitly defining it
by Anonymous Monk on Feb 14, 2013 at 16:40 UTC

    Huh. I thought you needed to use exists to avoid AVing the hash key you're reading, but that code works.

    This should simplify some of my code.

      My apologies, as it should be written as:

      ... if ( exists $Hash{$neededVal} and exists $Hash{$neededVal}{param1} and exists $Hash{$neededVal}{param1}{key1} ) { ...

      Will correct the original...

      Update: Replaced defined with exists. Thank you, choroba.

        What is wrong with plain old exists?
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Well, it only breaks for the false values like 0 or "" or undef.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re^2: Checking if hash value exists without implicitly defining it
by Anonymous Monk on Feb 15, 2013 at 10:04 UTC

    You don't even need the exists (assuming you don't have a weird freeform data structure):

    if (Hash{$neededVal} and $Hash{$neededVal}{param1} and $Hash{$neededVal}{param1}{key1} > 4) {

      Yes, you're correct! Originally omitted exists when not testing for the final value--then overgeneralized. However, testing $Hash{$neededVal}{param1}{key1} would fail when $Hash{$neededVal}{param1}{key1} == 0, but expliciting testing the value, as you've shown, would remedy that.