This is a subtlety I found with keys()
.
$ perl -e 'use warnings; use strict; my $d = { "ab" => 1 }; my @e = keys(%{$d->{cd}});'
$ perl -e 'use warnings; use strict; my $d = { "ab" => 1 }; my %e = %{$d->{cd}};'
Can't use an undefined value as a HASH reference at -e line 1.
I am most puzzled as to why the first snippet would not give an dereferencing error. When I use Data::Dumper
, it becomes clear that in the first snippet, $d->{cd}
, is autovivified to be {}
.
Why does keys
need to autovivify? I tried reading the perldoc
for it, could not find a satisfying answer. keys
does not set an alias ($_
, etc) so there is no need for perl to think $d->{cd}
needs to be in lvalue context, is there? (I understand if the expression needs to be in lvalue context autovivification happens as explained here.
A relevant post.
Note that keys can indeed be an lvalue (setting the hash's expected number of elements).
But even if keys itself isn't used in an lvalue context, it has a side effect of resetting a hash's iterator.
So it does modify the hash and so gives the dereference an lvalue context, which makes it autovivify.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With