How do I disable autovivification in Perl?

▼魔方 西西 提交于 2019-11-29 04:22:25
zoul

You might want to use an object instead of the hash (see Moose) or use a strict tied hash. Or you can turn warnings into errors, if you really want to:

use warnings NONFATAL => 'all', FATAL => 'uninitialized';
oeuftete

Relatively new is the autovivification module, which lets you do this:

no autovivification;

Pretty straightforward.

You can lock the hash using one of the functions from Hash::Util (a core module).

use Hash::Util qw( lock_keys unlock_keys );

my $some_ref = { akey => { deeper => 1 } };
lock_keys %$some_ref;

print "too deep" if $some_ref->{deep}{shit} == 1;

Now the last statement will throw an exception:

Attempt to access disallowed key 'deep' in a restricted hash

The downside is, of course, that you'll have to be very careful when checking for keys in the hash to avoid exceptions, i.e. use a lof of "if exists ..." to check for keys before you access them.

If you need to add keys to the hash again later you can unlock it:

unlock_keys %$some_ref;
$some_ref->{foo} = 'bar'; # no exception
Kent Fredric

I upvoted @zoul, but you should take it one step further.

Write Tests

You should have your code covered with tests, and you should run some of those tests with

use warnings FATAL => 'uninitialized';

declared in the test-case itself. Its the only way to address the concern you have with developers not checking things in advance properly. Make sure their code is tested.

And take it another step further, and make it easy to run your tests under Devel::Cover to get a coverage report.

cover -delete
PERL5OPT='-MDevel::Cover' prove -l 
cover -report Html_basic 

And then check the lines of code and statements are being executed by the tests, otherwise making those warnings fatal will just make code die at an unexpected time later.

daotoad

Another option is to use Data::Diver to access your data structures.

if( 1 == Dive($some_ref, qw/ deep structures are not autovivified now / )) {
    Do_Stuff();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!