haukex has asked for the wisdom of the Perl Monks concerning the following question:

This is a two-part question. First, as a followup to the explanations in Array dereference in foreach(), where the whole point was that autovivification happens in lvalue context, does it seem counterintuitive to anyone else that the last of the following doesn't throw an error, especially when compared to the second-to-last example? (inspired by this thread from today)

$ perl -wMstrict -MData::Dump -e' @{$a->{list}} =(); dd $a' { list => [] } $ perl -wMstrict -MData::Dump -e' for (@{$a->{list}}) {}; dd $a' { list => [] } $ perl -wMstrict -MData::Dump -e' my @x = @{$a->{list}}; dd $a' Can't use an undefined value as an ARRAY reference at -e line 1. $ perl -wMstrict -MData::Dump -e' my $x = @{$a->{list}}; dd $a' Can't use an undefined value as an ARRAY reference at -e line 1. $ perl -wMstrict -MData::Dump -e' my $x = $#{$a->{list}}; dd $a' { list => [] }

Second, it has bothered me that there doesn't appear to be a central reference on autovivification. The perldocs only mention it in one or two sentences, mostly perlref, but there isn't a section heading anywhere, explaining it overall, that I can link to. There also doesn't appear to be anything in Tutorials either, all I could find so far is the SoPW Explaining Autovivication plus one or two other threads, but no central place where it is all explained. Unless I have missed something - does anyone happen to know?

Update: Thanks for the replies everyone!

Update 2: There are a couple more interesting cases having to do with autovivification and changes to scalar in Why doesn't this die with "Can't use an undefined value as an ARRAY reference"?".

Replies are listed 'Best First'.
Re: Autovivification Oddity
by shmem (Chancellor) on Feb 11, 2018 at 13:27 UTC

    Your last example is comparable to

    perl -wMstrict -MData::Dump -e' my $x = $a->{list}->[0]; dd $a' { list => [] }

    since indexing autovivifies the anonymous array, as perlref explains. Retrieving its highest index is also a way of indexing.

    But I agree, autovivification is important enough to warrant a section on its own in e.g. perldata, which mentions it only once and refers to perlref.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Autovivification Oddity
by oiskuu (Hermit) on Feb 11, 2018 at 15:07 UTC

    Not an answer to your question, but I'd like to point out a thing about dereferencing.

    You can control (avoid) autovivification by taking a slice instead of plain dereference. One-element slices may raise a warning, though, so I guess this might count as a hack.

    $ perl -wMstrict -MData::Dump -e' my $x = $#{$$a{list}}; dd $a' { list => [] } $ perl -wMstrict -MData::Dump -e' my $x = $#{@$a{list}}; dd $a' Can't use an undefined value as an ARRAY reference at -e line 1.

    And to abuse it a little further: a slice in scalar context (imposed by dereference) yields its last value, so for instance

    $ perl -MData::Dump -e' my %h = map {$_ => {v => "x$_"}} qw(a b c); dd + @h{qw(a b c)}->{v};' "xc"

    Update. Forgot to mention: with recent enough perls that support postderef, one can change a straight deref into a slice simply by making an -> into ->@. Thus you may prevent autovivification at any level, e.g. $x->@{a}->@[5].

Re: Autovivification Oddity
by QM (Parson) on Feb 12, 2018 at 12:00 UTC