加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 为什么$foo – > {bar} autovivify但%$foo不?

发布时间:2020-12-15 21:15:35 所属栏目:大数据 来源:网络整理
导读:我有以下代码: $headers;some_sub( %$headers ); 当我调用some_sub时,我收到一个错误: Can’t use an undefined value as a HASH reference at … 但类似的代码不会产生错误: $headers-{ x }; 为什么自动复制在第一个示例中的工作方式与在第二个示例中的
我有以下代码:
$headers;
some_sub( %$headers );

当我调用some_sub时,我收到一个错误:

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没有启动,你得到了这个错误.

从perlglossary起自动化

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读