7 ms·
I have a list of Perl ‘wtf’ moments. The discovery of autovification was one of them. Perl autovivifies on existence checks. This has led to A LOT of bugs. Pa
by tkahnoski 8y ago
I have a list of Perl ‘wtf’ moments. The discovery of autovification was one of them.
Perl autovivifies on existence checks. This has led to A LOT of bugs.
Particularly since native Perl objects have all the behaviors of hashes so instead of getting the equivalent of a null exception Perl happily creates a hash and the process won’t bomb out until I try to call a method on the hash which I was expecting as a particular type.
In legacy code, this has led to a lot of safety checks verifying the variable is actually the expected type.
- braythwayt 8y agoAutovivifying variables is wildly out there. I feel your pain! Autovivifying properties of a dictionary could certaintly lead to some bugs, but as presented here, checking for existence won’t invoke autovivification.
- tkahnoski 8y agoIndeed. I wish with Perl I had a way to be explicit about when I could disable this behavior but its builtin to the language to such a degree to be unavoidable. (Using different Perl object frameworks and getter/setter methods is a possibility to protect against this class of error) The implementation provided in the article is at least a known property of that particular object type and not a property of all objects.
- draegtun 8y agoYou can switch off or amend autovivification behaviour using this pragma module - https://metacpan.org/pod/autovivification https://metacpan.org/pod/autovivification no autovivification; # switches off autoviv except for setting no autovivification 'exists'; # just for exists checks
- tkahnoski 8y agoOMG. All I have to say is thank you.
- joosters 8y agoIn perl, you can also make hashes ‘const’ at any time, so accesses to non-existent keys will throw an error. This is also a great way to prevent dumb code typos in hash key names.
- lizmat 8y agoPerl 5 has a problem with multilevel existence checks. Unfortunately this has been part of Perl 5 for such a long time that too many programs depend on this behaviour. Attempts at fixing this behaviour have all been reverted as far as I know. Perl 6 does not have that problem. One can even bind an alias to non-existing keys in a hash (several levels deep) only to have vivification happen as soon as you assign to the alias. my %h; my $deep := %h<a><b><c>; say %h<a>:exists; # False say %h<a><b>:exists; # False say %h<a><b><c>:exists; # False $deep = 42; say %h<a><b><c>:exists; # True