在哈希中存储哈希

时间:2011-07-03 20:13:46

标签: perl hash

我遇到了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)

3 个答案:

答案 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语言的基本信息。