Programmers_must_be_bald Programmers_must_be_bald - 6 months ago 11
Perl Question

Fixing keys that spring into existence when calling exist on a nested hash

Dear Stackoverflowers,

When calling exist on a hash for testing the existence of keys much further nested in a hash that does not exist, it will create keys leading to final test to see if the final key exist.

The example from perldoc exists is such:

undef $ref;
if (exists $ref->{"Some key"}) {}
print $ref; # prints HASH(0x80d3d5c)


I absolutely love the autovification feature of perl; however, I am now absolutely frightened of using exists for any future projects I may have.

Does anyone know if and/or how one may edit the library perl uses exists from or perhaps use a module to correct for this? It is really silly that if it does not exist, it makes one to see if future keys will exist.

Lastly, learning from the question below in Checking for existence of hash key creates key, one of the comments states OO-style for deeply nested hashes are suggested. Will there be any technical issues with deeply nested (>n=10) and high memory (>8GB) with very simple floating values stored in these nested hashes? Or just issues like this one?

Answer

Dereferencing undefined variables[1] is what causes autovivification[2]. Examples of dereferencing:

  • $ref->{key} and ${$ref}{key}
  • $ref->[0] and ${$ref}[0]
  • $$ref
  • @$ref
  • etc.

You can avoid it by replacing

exists( $ref->{"Some key"} )

with

$ref && exists( $ref->{"Some key"} )

or by adding

no autovivification;

  1. Under certain circumstances.

  2. "Autovivification" can also be used to refer to the creation of non-existent variables ($x = 1;), elements of hashes (my %h; $h{$key} = 1;) and elements of arrays (my @a; $a[3] = 1;). This post does not address these as it is not relevant here.

Comments