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

Hi all,

I have come across this strange (at least to me) behaviour of perl interpreter. Let me give you an example:

perl -We'use strict; my $a; my $b = %{ $a }'
This unsurprisingly gives a run time error "Can't use an undefined value as a HASH reference". But then I would think that so does any of these:
perl -We'use strict; my $a; my @b = map { $_ } %{ $a }' perl -we'use strict; sub foo {}; my $a; foo( @{ $a } )'

Instead it seems that perl in this case (function context?) just translates those hash or array dereferences to empty structure and gives no error.

Can somebody explain what is going on here?

(Tested with perl 10, 14 and 20.)

Replies are listed 'Best First'.
Re: Strange behaviour of interpreter when dereferencing an undefined value
by ikegami (Patriarch) on Nov 02, 2014 at 11:00 UTC

    References in lvalue context autovivify.

    %{ $a } in lvalue context is effectively %{ $a //= {} }

    @{ $a } in lvalue context is effectively @{ $a //= [] }

    For example,

    >perl -MData::Dumper -E"my $ref; $ref->{a}{b} = 'c'; print Dumper $x;" $VAR1 = { 'a' => { 'b' => 'c' } };

    As you can see, $x->{a}{b} in lvalue context is effectively ( ( $x //= {} )->{a} //= {} )->{b}.

    You can control the behaviour using the autovivification module. (Don't file a bug report.)

      I can't see how this could be related to my examples since in
      perl -we'use strict; sub foo {}; my $a; foo( %{ $a } )'
      the expression %{ $a } isn't in lvalue context. Also autovivification doesn't appear only in lvalue context:
      perl -MData::Dumper -we'use strict; my $a; $a->{b}{c}; print Dumper $a +' $VAR1 = { 'b' => {} };

        the expression %{ $a } isn't in lvalue context.

        Yes, it is.

        $ perl -E'sub f { $_[0] = 'abc' } f($x); say $x' abc $ perl -E'sub f { $_[1] = 'abc' } $h{a}=undef; f(%h); say $h{a}' abc

        Perl arguments are always passed by reference.

        Also autovivification doesn't appear only in lvalue context

        I didn't say otherwise.

Re: Strange behaviour of interpreter when dereferencing an undefined value (missing warning, perl doesn't warn for all cases)
by Anonymous Monk on Nov 02, 2014 at 09:56 UTC