I am trying to turn off autovivication using the module: https://metacpan.org/pod/autovivification but it is failing for grep:
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':all';
use DDP;
no autovivification;
my %h = (
'a' => 1,
'b' => 2,
);
p %h; # pretty print the original hash
my @fake_keys = ('x', 'y', 'z');
if (grep {defined} @h{@fake_keys}) {
say "found fake keys";
}
p %h; # show that 'x', 'y', & 'z' are added as undef keys
How can I turn off autovivication for grep?
Solution:
Explanation follows.
Autovivification, as used in the Perl documentation, is the creation of anon vars and references to them when an undefined scalar is dereferenced.
For example, autovivification dictates that
$x->[0]is equivalent to( $x //= [] )->[0].For example, autovivification dictates that
$h{p}{q}is equivalent to( $h{p} //= {} )->{q}.There is no dereferencing in your code, so autovivifaction couldn't possibly occur in your code, so
no autovivification;doesn't help.What you have in your code is a hash element used as an lvalue. "lvalue" means assignable value. It's named after the fact that such expressions are usually found on the left of assignments.
But they are also found elsewhere in Perl.
This is because the block of each of looping constructs can modify the items being processed by modifying
$_, and subs can modify their arguments my modifying the elements of@_.For that to be possible,
$h{$k}must exist before the loop body is entered or the sub is called.Sub calls use expensive magic to avoid this.
But
grepandmapdo not.