Perl Iron Man rules specifically said we could blog about what we hate; the nasty habit that Perl has to autovivificate hashes when you don't expect it to, is one of them.
autovivification in itself is a good thing and is useful in many places [1], but at times, it's just plain aweful:
Here is a first nasty effect in a common idiom:
$ my %hash = ( x => 1);
$ exists $hash{x}
1
$ exists $hash{meta}
$ exists $hash{meta}{z}
$ exists $hash{meta}
1
And now here is a second common idiom that can be fatal:
$ my $hash = {}
$HASH1 = {};
$ for (keys %{ $hash->{meta} }) {
> print "$_\n";
> }
$ $hash
$HASH1 = { meta => {} };
Each time, the 'meta' hash has been autovivicated when deferenced, the problem is that it's quite easy to oversee that fact and somewhere else do in the code:
unless (exists $hash->{meta}) {
do_something_really_important($hash); # will install $hash->{meta}
}
## code that relies on $hash->{meta} to have meaningful informations
Where you can, completely avoid to evaluate conditions based on the presence of a hash in your hash, because this can lead to silent and painful bugs. Calling method calls on objects where it's possible is one option, or use another indicator that do_something_really_important() needs to be called...
To finish with a bit of love after all this hate: re.pl is awesome and you can get it here (checkout MultiLine PPI plugin too):