Note添加到问题中的代码演示了为什么自动生存不会发生。
Short你的 sub 接受一个列表(哈希),其中有一个匿名数组作为元素 - 并且%$headers
就埋在那个阵中。它是匿名数组这是别名的标量,因此不需要%$headers
可修改。因此,不会发生自动生存,并且您会收到下面描述的致命运行时错误,因为尝试对未定义的引用进行取消引用。
A %$ref
使用时会自动复活左值上下文。这可能发生在子调用中,见下文。
您显示的错误是由于使用未定义的引用造成的。例如,声明
my %hash = %{ $ref };
尝试从存储在的内存位置复制哈希值$ref
并将其分配给%hash
。符号%hash
是在编译时创建的,但是如果没有找到哈希值$ref
或者如果里面什么都没有$ref
,我们得到一个错误。这里没有发生自动生存。和use strict
有效
perl -wE'use strict; my $h; my %h = %$h; say $h'
这会引发致命的运行时错误
Can't use an undefined value as a HASH reference at -e line 1.
When eval
-ed 生存下去
perl -wE'use strict; my $h; my %h = eval { %$h }; say $h; say "hi"'
它打印一条关于“未初始化值",一个空行,然后hi
。没有哈希。
但是,当在子例程调用中用作参数时,它会自动激活
perl -wE'use strict; sub tt { 1 }; my $h; tt( %$h ); say $h'
因为这会打印该行HASH(0x257cd48)
,没有警告或错误。
当取消引用的对象用于左值上下文,这意味着它需要可修改。在子例程调用中,其原因是函数的参数被别名为@_
所以必须可以修改它们。同样的别名需求使得它发生在foreach
循环,同时keys
重置哈希迭代器。看这个帖子 https://stackoverflow.com/questions/6419618/perl-vivification-question-while-dereferencing-undefined-array-reference and 这个帖子 https://stackoverflow.com/questions/2206836/why-does-perl-autovivify-in-this-case and 这个帖子 https://stackoverflow.com/questions/35029084/why-does-autovivification-occur-with-keys-and-not/35031218#35031218.
谢谢这套衣服是黑色的不是 https://stackoverflow.com/users/176646/thissuitisblacknot以获得解释和链接。
在你的情况下%$ref
作为匿名数组的元素传递,因此没有别名(arrayref 本身是)。所以自动激活不会启动,你会得到这个错误。
On 自动活化 from 术语表 http://perldoc.perl.org/perlglossary.html#A
在 Perl 中,存储位置(左值)根据需要自动生成,包括创建任何硬引用值以指向下一级存储。分配$a[5][5][5][5][5] = "quintet"
可能会创建五个标量存储位置,加上四个引用(在前四个标量位置),指向四个新的匿名数组(以保存最后四个标量位置)。但自动生存的要点是你不必担心它。
另请参阅,例如有效佩勒的文章 https://www.effectiveperlprogramming.com/2011/04/understand-autovivification/