0

Using Perl v5.22.1 on Windows 10 x64. I have set

use strict;
use warnings;

This code (based on accepted answer in this question by @Jeef) is part of a while loop parsing a file. It silently exits:

my %hvac_codes;   # create hash of unique HVAC codes
#Check the hash to see if we have seen this code before we write it out
if ( $hvac_codes{$hvacstring}  eq 1)  {
    #Do nothing - skip the line
} else {
  $hvac_codes{$hvacstring} = 1;  
}

If I change it like this

my %hvac_codes;   # create hash of unique HVAC codes
#Check the hash to see if we have seen this code before we write it out
if ( defined $hvac_codes{$hvacstring} )  {
    #Do nothing - skip the line
} else {
  $hvac_codes{$hvacstring} = 1;  
  print (" add unique code $hvacstring \n");
}

it does not silently exit (also curious as to why silent exit rather than error on undefined reference) but does not work as expected. Every $hvacstring gets added to the %hvac_codes hash, even if they have been added. (as evidenced by print)

I wanted to see how the hash ended up to determine if every code is treated as undefined because the test is wrong, or the assignment into the hash is not working. I tried dumper two ways:

print dumper(%hvac_codes);

and (based on this question's answer)

print dumper(\%hvac_codes);

In both cases the dumper line fails with the Global symbol "%hvac_codes" requires explicit package name error, even though my %hvac_codes; is present. For now I have commented it out.

tim11g
  • 1,935
  • 5
  • 27
  • 41
  • For anyone who finds this later, the correct syntax for using Dumper on a hash is: `print Dumper(%hvac_codes);` The leading backslash form did not work in this case. – tim11g May 17 '20 at 20:23
  • For anyone else who finds this later, the correct syntax for using `Data::Dumper` on a hash is `print Dumper(\%hvac_codes)`. Without the leading backslash, the hash keys and values are treated as separate scalars. – mob May 17 '20 at 21:57

1 Answers1

3

In Perl, a key in a hash either exists or not. To check the existence of a key, use exists.

if (exists $hvac_codes{$hvacstring}) { ...

You can also test for definedness of the value corresponding to the key using defined.

if (defined $hvac_codes{$hvac_string}) { ...

If the key doesn't exist, it still returns false; but it also returns false for keys whose assigned value is undef:

undef $hvac_codes{key_with_undef_value};

Note that Data::Dumper exports Dumper, not dumper. Perl is case sensitive.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • 1
    Fixed it! Once I got Dumper working, I quickly saw that only one line was ending up in hash %hvac_codes. The problem was I forgot to move the `my %hvac_codes;` outside the main while loop and it was getting re-initialized each time through. I ended up with the test looking like this `if (( exists $hvac_codes{$hvacstring} ) and ( $hvac_codes{$hvacstring} eq 1 )) {` – tim11g May 17 '20 at 20:20