在 perl 中构建可变深度哈希引用数据结构
Posted
技术标签:
【中文标题】在 perl 中构建可变深度哈希引用数据结构【英文标题】:Building a variable depth hash reference data structure in perl 【发布时间】:2010-07-21 17:50:22 【问题描述】:我需要在 perl 中构建一个可变深度的哈希数据结构。最终我找到了这段代码:
#!/usr/bin/perl -w
use strict;
my %hash;
my $value = "foo";
my @cats = qw(a b c d);
my $p = \%hash;
foreach my $item (@cats)
$p->$item = unless exists($p->$item);
$p = $p->$item;
我的问题是它如何以及为什么起作用。我以为我知道 perl 是如何工作的。在这段代码中,我没有看到 \%hash 值被重置,并且似乎 $p (这是一个局部变量)在每个循环中都被重置。我什至可以通过数据转储器看到它: 运行:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my %hash;
my $value = "foo";
my @cats = qw(a b c d);
my $p = \%hash;
foreach my $item (@cats)
print "BEFORE:\n";
print Dumper(\%hash);
#print Dumper($p);
$p->$item = unless exists($p->$item);
$p = $p->$item;
print "AFTER:\n";
print Dumper(\%hash);
#print Dumper($p);
然后用
取消注释该行#print Dumper($p)
清楚地表明 $p 每次都是一个新变量。
如果 $p 每次都重置,\%hash 是如何构建的?
【问题讨论】:
【参考方案1】:$p
不是每次都被“重置”;它被设置为哈希中的下一个较低级别,即刚刚添加的级别。此时它只是一个空的 hashref,,因为它将在下一次循环迭代中填充。
我不确定您如何得出结论,$p
每次都是一个新变量,但这是不正确的。它只是指向%hash
结构中的一个新位置。由于它是在循环之外声明的,因此它不会随着循环的迭代而丢失其值。
【讨论】:
【参考方案2】:向$p
所指的哈希添加一个显式标记:
...
print "AFTER:\n";
$p->'$p' = 'is here!';
print Dumper(\%hash);
delete $p->'$p';
那么最后几个 AFTER 转储看起来像
之后: $VAR1 = '一个' => 'b' => 'c' => '$p' => '来了!' ; 后: $VAR1 = '一个' => 'b' => 'c' => 'd' => '$p' => '来了!' ;
是的,在每个新的深度,$p
指的是一个空哈希,但退后一步查看%hash
的整体结构。
【讨论】:
【参考方案3】:想看一些很酷的东西吗?这做同样的事情(只是你永远不会看到它分配了 hashref!)
my $p = \\%hash; # $p is a reference to a hashref
foreach my $item (@cats)
# because $p references a reference, you have to dereference
# it to point to the hash.
$p = \$$p->$item unless exists $$p->$item;
当你引用它时,槽位是autovivified,当它像哈希引用一样被寻址时,它会创建那个哈希引用。
【讨论】:
以上是关于在 perl 中构建可变深度哈希引用数据结构的主要内容,如果未能解决你的问题,请参考以下文章