On Sat, Jul 13, 2019 at 4:52 PM Karen Etheridge <perl@froods.org> wrote: > On Sat, Jul 13, 2019 at 10:43 AM Deven T. Corzine <deven@ties.org> wrote: > > > I would love to have the other discussion about whether the current > behavior could be changed (perhaps with a pragma) to avoid autovivification > > We have one. > > no autovivification; > > See https://metacpan.org/pod/autovivification. > Thanks for pointing that out! I was aware of that module, but some people who weren't aware of it might find it useful. While this module is good for calling attention to unexpected autovivification (only when it actually occurs), it doesn't quite provide the behavior I was suggesting. For example, here is the default behavior, which autovivifies two new hashes nested under $x due to a simple read-only access in non-existent sub-hashes: $ perl -MData::Dx -e 'my $x = { foo => { bar => {} } }; Dx $x; $y = > $x->{foo}{bar}{testing}{autovivification}{pragma}; Dx $y; Dx $x;' > #line 1 -e > $x = { foo => { bar => {} } } > #line 1 -e > $y = undef > #line 1 -e > $x = { foo => { bar => { testing => { autovivification => {} } } } } At first glance, "no autovivification" appears to fix this: $ perl -MData::Dx -e 'no autovivification; my $x = { foo => { bar => {} } > }; Dx $x; my $y = $x->{foo}{bar}{testing}{autovivification}{pragma}; Dx $y; > Dx $x;' #line 1 -e > $x = { foo => { bar => {} } } > #line 1 -e > $y = undef > #line 1 -e > $x = { foo => { bar => {} } } However, if you use that non-existent reference as a subroutine parameter, the same problem comes back: $ perl -MData::Dx -e 'no autovivification; sub foo { return $_[0]; }; my $x > = { foo => { bar => {} } }; Dx $x; my $y = > foo($x->{foo}{bar}{testing}{autovivification}{pragma}); Dx $y; Dx $x;' > #line 1 -e > $x = { foo => { bar => {} } } > #line 1 -e > $y = undef > #line 1 -e > $x = { foo => { bar => { testing => { autovivification => {} } } } } My guess is that this relates to subroutine parameters being passed by reference. Using a hard reference actually autovivifies even deeper: $ perl -MData::Dx -e 'no autovivification; my $x = { foo => { bar => {} } > }; Dx $x; my $y = \$x->{foo}{bar}{testing}{autovivification}{pragma}; Dx > $y; Dx $x;' > #line 1 -e > $x = { foo => { bar => {} } } > #line 1 -e > $y = \undef > #line 1 -e > $x = { > foo => { > bar => { testing => { autovivification => { pragma => > undef } } }, > }, > } The default options for "no autovivification" are "fetch exists delete". Adding "store" to this list does catch the autovivification attempt, but defaults to a fatal error: $ perl -MData::Dx -e 'no autovivification qw[fetch exists delete store]; > sub foo { return $_[0]; }; my $x = { foo => { bar => {} } }; Dx $x; my $y = > foo($x->{foo}{bar}{testing}{autovivification}{pragma}); Dx $y; Dx $x;' > #line 1 -e > $x = { foo => { bar => {} } } > Can't vivify reference at -e line 1. You can add "warn" to the options to make this non-fatal: $ perl -MData::Dx -e 'no autovivification qw[fetch exists delete store > warn]; sub foo { return $_[0]; }; my $x = { foo => { bar => {} } }; Dx $x; > my $y = foo($x->{foo}{bar}{testing}{autovivification}{pragma}); Dx $y; Dx > $x;' > #line 1 -e > $x = { foo => { bar => {} } } > Reference was vivified at -e line 1. > Reference was vivified at -e line 1. > #line 1 -e > $y = undef > #line 1 -e > $x = { foo => { bar => {} } } There appears to be no way to suppress the autovivification silently. Regardless, including "store" in the options also prevents autovivification which might be wanted: $ perl -MData::Dx -e 'no autovivification qw[fetch exists delete store > warn]; sub foo { return $_[0]; }; my $x = { foo => { bar => {} } }; Dx $x; > my $y = foo($x->{foo}{bar}{testing}{autovivification}{pragma}); Dx $y; Dx > $x; $x->{foo}{bar}{testing}{autovivification}{pragma} = 1;' > #line 1 -e > $x = { foo => { bar => {} } } > Reference was vivified at -e line 1. > Reference was vivified at -e line 1. > #line 1 -e > $y = undef > #line 1 -e > $x = { foo => { bar => {} } } > Reference was vivified at -e line 1. > Reference was vivified at -e line 1. > Modification of a read-only value attempted at -e line 1. In this example, including "store" in the options is breaking the assignment at the end. Would this module have even been written if it weren't for the pitfalls of Perl's current autovivification behavior? It seems to be intended as a tool to help fix code that might break due to unintended autovivification. Such situations arise very easily with "read-only" autovivification, but if Perl did autovivification only when actually necessary, there would be much less value in disabling it. DevenThread Previous | Thread Next