Search code examples
perlparsingperl-data-structures

Nicer way to test if hash entry exists before assigning it


I'm looking for a nicer way to first "test" if a hash key exists before using it. I'm currently writing a eventlog parser that decodes hex numbers into strings. As I cannot be sure that my decode table contains hex numbers I first need to check if the key exists in a hash before assigning the value to a new variable. So what I'm doing a lot is:

if ($MEL[$i]{type} eq '5024') {
  $MEL[$i]{decoded_inline} = $decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"}
    if exists ($decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"})
}

What I do not like is that the expression $decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"} is twice in my code. Is there a nicer or shorter version of the line above?


Solution

  • Yes there is an easier way. You know that you can only store references in an array or hash, right? Well, there's a neat side effect to that. You can take references to deep hash or array slots and then treat them like scalar references. The unfortunate side-effect is that it autovivifies the slot, but if you're always going to assign to that slot, and just want to do some checking first, it's not a bad way to keep from typing things over and over--as well as repeatedly indexing the structures as well.

    my $ref = \$decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"};
    unless ( defined( $$ref )) { 
        ...
        $$ref = {};
        ...
    }