Michael Sun
Michael Sun

Reputation: 61

perl check existence of a hash key when there is value at the same level in strict refs check

For the following code with strict check, it will raise an error.

use strict;
my $a;
my $b;
my $c;

my %database;
$database{'a'}{'b'}{'c'} = 'e';
$database{'a'}{'b'}{'c'}{'d'} = 'f';
foreach my $a (keys %database){
  foreach my $b (keys %{$database{$a}}){
    foreach my $c (keys %{$database{$a}{$b}}){
      if (exists $database{$a}{$b}{$c}{'d'}){print "success!\n";}
    }
  }
}

Error message:

Can't use string ("e") as a HASH ref while "strict refs" in use at test.pl line 8.

Value 'e' and key 'd' is at the same level. When "exists" tries to find key d, the debugger will find there are values at the same level and raise the error, because 'e' is not a key to check. How do I solve it when keeping the structure of hash and the use of strict?

Yes it would raise an error at line 8. Actually another one created this hash without strict in one file and when I wrote another part in another file, I have strict and it raises such a problem.

Upvotes: 0

Views: 110

Answers (2)

ikegami
ikegami

Reputation: 386696

The following stores a string in $database{'a'}{'b'}{'c'}:

$database{'a'}{'b'}{'c'} = 'e';

But the following expects $database{'a'}{'b'}{'c'} to be a reference:

$database{'a'}{'b'}{'c'}{'d'} = 'f';

Assuming you can have values at any level, you need to change your data structure to something like the following:

$database{a}{children}{b}{children}{c}{value} = 'e';
$database{a}{children}{b}{children}{c}{children} = 'f';

Upvotes: 4

ysth
ysth

Reputation: 98508

If you want to not do the check unless the c-level is a hash, just check that:

if (ref $database{$a}{$b}{$c} ne 'HASH') {
    print "not a hash\n";
}
elsif (exists $database{$a}{$b}{$c}{'d'}){
    print "success!\n";
}

Upvotes: 3

Related Questions