我遇到了Perl脚本的麻烦。我尝试在哈希中存储哈希。这个剧本很简单:
use Data::Dumper;
my %h1=();
$h1{name}="parent";
my %h2=();
$h2{name}="child";
$h1{nested}=%h2; # store hash h2 in hash h1
print "h2:\n";
print Dumper(%h2); # works
print "h1{nested}:\n";
print Dumper($h1{nested}); # fails
结果:
h2:
$VAR1 = 'name';
$VAR2 = 'child';
h1{nested}:
$VAR1 = '1/8';
为什么$ h1 {nested}不会被转储为哈希值,而是作为某种奇怪的标量(1/8)?
PS:即使这个问题听起来微不足道 - 我搜索了SO,但没有发现它之前被问过。 PPS:我的Perl是为x86_64-linux-gnu-thread-multi构建的v5.10.1(*) (有53个已注册的补丁,有关详细信息,请参阅perl -V)答案 0 :(得分:13)
您只能在哈希中存储 hashref :
$h1{nested}=\%h2;
然后您可以通过
访问%h2
的名称
$h1{nested}->{name}
在你的代码中,%h2被强制为标量上下文,它会显示“1/8”值,并存储该值。
答案 1 :(得分:5)
在perl中,存储在列表(散列或数组)中的值始终为标量。鉴于此,将哈希存储在另一个哈希中的唯一方法是存储对它的引用。
$h1{'nested'} = \%h2;
或
$h1{'nested'} = { 'name'=>'child' };
(右侧的大括号是对匿名哈希的引用)。
顺便说一句,不引用密钥中的文字通常被视为不良做法,请参阅here答案 2 :(得分:4)
为什么$ h1 {nested}不会被转储为哈希值,而是作为某种奇怪的标量(1/8)?
因为您将其存储在标量上下文中!
执行此操作时:
$h1{nested} = %h2;
你正在存储一个标量。由于%h2
是哈希值,因此您将获得ol'分数字符串。根据{{3}}
如果在标量上下文中计算哈希值,则在哈希值为空时返回false。如果有任何键/值对,则返回true;更准确地说,返回的值是一个字符串,由使用的桶数和分配的桶数组成,用斜杠分隔。
这解释了你得到的1/8
。
您需要做的是将哈希存储为另一个哈希中的引用。正如其他人指出的那样,它应该是:
$h1{nested} = \%h2;
哈希名称前面的反斜杠为您提供存储哈希的内存位置。您可以使用花括号,但我更喜欢反斜杠表示法。
查看计算机上的Perldoc website(或我链接到的网页)。这将告诉您如何制作列表,哈希或哈希列表,哈希列表和列表哈希等内容。只是一个字o`警告:如果你太复杂了,就很难维护,所以一旦你玩得开心,看看perldoc prelreftut
。
perldoc
命令包含许多Perl文档,包括所有Perl函数,系统上安装的Perl模块,甚至是有关Perl语言的基本信息。