$headers; some_sub( %$headers );
Can’t use an undefined value as a HASH reference at …
$headers->{ x };
为什么自动复制在第一个示例中的工作方式与在第二个示例中的工作方式不同?
UPD
我注意到@ThisSuitIsBlackNot.我真的问:
why my $h; $h->{foo} works and my $h; %$h doesn’t
UPD
真正的代码:
my $email = Email::Simple->create((),header => [(),To => $address,From => $cnf->{ from },Subject => $subject,'Content-Type' => 'text/html; charset="utf8"',%$headers ],body => $body );
解决方法
你的sub采用一个列表(哈希),它有一个匿名数组作为元素 – %$headers隐藏在该数组中.这是anon数组
这是标量别名,因此不需要%$标题可修改.因此,不会发生自动生成,并且您将获得下面描述的致命运行时错误,因为尝试对未定义的引用进行解除引用.
在左值上下文中使用时,%$ref会自动生成.这可能发生在子呼叫中,见下文.
my %hash = %{ $ref };
尝试从存储在$ref中的内存位置复制哈希并将其分配给%hash.符号%hash是在编译时创建的,但如果在$ref中找不到散列或者$ref中没有任何内容,则会出现错误.这里没有自动生成.使用严格有效
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.
当评估生存时
perl -wE'use strict; my $h; my %h = eval { %$h }; say $h; say "hi"'
它打印一个关于“未初始化的值”的警告,一个空行,然后你好.没有哈希.
perl -wE'use strict; sub tt { 1 }; my $h; tt( %$h ); say $h'
因为这会打印行HASH(0x257cd48),没有警告或错误.
当在左值上下文中使用解除引用的对象时,会发生自动生成,这意味着它需要是可修改的.在子例程调用中,原因是函数的参数在@_中有别名,因此必须可以修改它们.相同的别名需要使它在foreach循环中发生,而键重置散列迭代器.见this post和this post和this post.
感谢ThisSuitIsBlackNot的解释和链接.
在你的情况下,%$ref作为匿名数组的元素传递,因此没有别名(arrayref本身是).所以autvivication没有启动,你得到了这个错误.
In Perl,storage locations (lvalues) spontaneously generate themselves as needed,including the creation of any hard reference values to point to the next level of storage. The assignment
$a[5][5][5][5][5] = "quintet"
potentially creates five scalar storage locations,plus four references (in the first four scalar locations) pointing to four new anonymous arrays (to hold the last four scalar locations). But the point of autovivification is that you don’t have to worry about it.
另请参阅,例如,article from Effective Pearler