Cargo Cult Programming: Generating Code in the hope it may achieve something
... without fully understanding what is going on.
https://en.wikipedia.org/wiki/Cargo_cult
One such example is InternalVal. The author might have heard - and be afraid - of "autovivification". Perls way to bring e.g. hash structures automatically to life when you add some data deep nested within (hash of hash of ...), but the underlying structures do not exist yet.
Now - I am changing InternalVal
sub InternalVal {
my ($d, $n, $default) = @_;
return $defs{$d}{$n} if (defined $defs{$d} && defined $defs{$d}{$n});
return $default;
}
but it should not be just about some reformatting. Using "defined" on a hash value will not help much with the subsequent defined, if the actual value of defs{
d} is not a hashref itself. Consider the following:
my %defs;
$defs{foo} = {};
say InternalVal('foo','bar','default');
$defs{foo} = { bar => 'blah'};
say InternalVal('foo','bar','default');
$defs{foo} = 'blah';
say InternalVal('foo','bar','default');
say "I will (not) survive!";
sub InternalVal {
my ($d, $n, $default) = @_;
return $defs{$d}{$n} if (defined $defs{$d} && defined $defs{$d}{$n});
return $default;
}
In this case, the first two calls to InternalVal will work ok, whereas the 3rd call will fail and crash Perl Can't use string ("blah") as a HASH ref while "strict refs" in use
.
Of course, because $defs{foo} is not a hashref, but it is defined... boom. This code will survive:
sub InternalVal {
my ($d, $n, $default) = @_;
return $defs{$d}{$n} if (ref $defs{$d} eq 'HASH'
&& defined $defs{$d}{$n});
return $default;
}