I have the following code:
$headers;
some_sub( %$headers );
When I call some_sub I get an error:
Can't use an undefined value as a HASH reference at ...
But similar code does not produce an error:
$headers->{ x };
Why doesn't autovivification work the same way in the first example as it does in the second?
UPD
I noted by @ThisSuitIsBlackNot. I really ask:
why my $h; $h->{foo} works and my $h; %$h doesn't
UPD
The real code:
my $email = Email::Simple->create(
header => [
To => $address,
From => $cnf->{ from },
Subject => $subject,
'Content-Type' => 'text/html; charset="utf8"',
%$headers,
],
body => $body
);
Note Code added to the question demostrates why autovivification doesn't happen.
Short Your sub takes a list (hash) which has an anonymous array as an element – and
%$headersis buried in that array. It is the anon array that is the scalar aliased to, thus there is no requirement for%$headersto be modifiable. Thus no autovivification happens, and you get the fatal runtime error described below, as dereferencing is attempted on an undefined reference.A
%$refautovivifies when used in lvalue context. This may happen in a sub call, see below.The error you show is due to the use of an undefined reference. For example, the statement
attempts to copy a hash from the memory location stored in
$refand assign it to%hash. The symbol%hashis created at compile time, but if no hash is found at$refor if there is nothing in$ref, we get an error. No autovivification happens here. Withuse strictin effectthis throws the fatal runtime error
When
eval-ed to survive thatit prints a warning about "uninitialized value", an empty line, and then
hi. No hash.However, when used as an argument in a subroutine call it autovivifies
as this prints the line
HASH(0x257cd48), without warnings or errors.The autovivification happens when a dereferenced object is used in lvalue context, which means that it needs to be modifiable. In a subroutine call the reason for this is that arguments to a function are aliased in
@_so it must be possible to modify them. The same aliasing need makes it happen in aforeachloop, whilekeysresets the hash iterator. See this post and this post and this post.Thanks to ThisSuitIsBlackNot for explanation and links.
In your case the
%$refis passed as an element of an anonymous array, and is thus not aliased (the arrayref itself is). So autovivication does not kick in and you get that error.On autovivification from perlglossary
Also see, for example, an article from Effective Perler