在Perl中,如何从HashRef数组中的引用访问值?

在Perl中,如何从HashRef数组中的引用访问值?,perl,reference,Perl,Reference,我有一系列对匿名哈希的引用。从对该数组的引用,$allDirArray,我想访问与键'dir'对应的值。目前我收到错误信息: Can't use string ("HASH(0x100878050)") as a HASH ref while "strict refs" in use at nameOfProgram.pl line 148. 看 现在,我想我对你的问题有了正确的诊断。因此,FAQ可能会有所帮助。我看不出您引用的代码有什么问题,所以我编写了一个简短的测试脚本,并通过Perl传递

我有一系列对匿名哈希的引用。从对该数组的引用,
$allDirArray
,我想访问与键
'dir'
对应的值。目前我收到错误信息:

Can't use string ("HASH(0x100878050)") as a HASH ref while "strict refs" in use at nameOfProgram.pl line 148. 看


现在,我想我对你的问题有了正确的诊断。因此,FAQ可能会有所帮助。

我看不出您引用的代码有什么问题,所以我编写了一个简短的测试脚本,并通过Perl传递

$$allDirArray[$i]->{'dir'}
#! perl
use warnings;
use strict;

my $allDirArray = [{dir => "b"},{c => "d"}];
my $i = 0;
my $tempDir = ${$allDirArray}[$i]{'dir'};
print "$tempDir\n";
如上所述,在Cygwin上使用Perl 5.10,程序运行如下:

$ perl allarraydir.pl
b
没有打印错误消息。看

编辑 在加入telemachus的建议后,我在上述程序的末尾添加了以下代码

# The following addition was included re telemachus's comment
my @allDirArray2 = ({dir => "b"},{c => "d"});
$tempDir = ${$allDirArray2}[$i]{'dir'};
print "$tempDir\n";
再次运行,并收到以下错误消息:

$ perl allarraydir.pl Global symbol "$allDirArray2" requires explicit package name at allarraydir.pl line 10. Execution of allarraydir.pl aborted due to compilation errors. $perl allarraydir.pl 全局符号“$allDirArray2”要求在 allarraydir.pl第10行。 由于编译错误,allarraydir.pl的执行已中止。
(这实际上应该是对您的问题的注释,而不是答案,但代码太长。)

错误消息表明您实际上正在尝试使用字符串“
哈希(0x100878050)
”作为hashref。因此,我怀疑您已经设法将哈希字符串化(即,您将它们用作字符串,而Perl将它们转换为字符串)。一种可能发生这种情况的方法是,将hashref分配给哈希键(哈希键只能是字符串),或者在分配中引用变量,如“
$array[0]=”$hashref”

所以在
${$allDirArray}[$i]
中有一个字符串,它包含“HASH(0x100878050)”,字面意思是字符串中的HASH。不是杂碎

确认这一点的最佳方法可能是转储数据结构。您可以通过以下方式执行此操作:


不知何故,您成功地将匿名哈希设置为字符串

下面是一个导致该错误的简短示例

use strict;
use warnings;

my $allDirArray = [ ''.{ 'dir' => 'somedir' } ];

my $tempdir = ${$allDirArray}[0]{'dir'};
# or
my $tempdir = $allDirArray->[0]{'dir'};
在nameOfProgram.pl第8行使用“strict refs”时,不能将字符串(“HASH(0x8555168)”用作HASH ref。
我是PerlMonks的参考资料的粉丝:如果你不太喜欢箭头,请注意
$allDirArray->[$I]{dir}
也可以。@Telemachus我想要我的箭头@西南:事实上,我注意到你对它们的偏爱。我自己也省略了,但我对此感觉不是很强烈。我评论中的“你”实际上是一般意义上的“有一天路过并读到这种”你。但是你(你所知道的具体的和一般的)知道这一点我删除了所有多余的箭头,但这是一种风格偏好,就像访问所有alpha散列键时使用引号一样。@Ether:等等-省略箭头,但保留引号?请看,现在,这是错误的。
$$
没有必要。如果在程序中编写$$而不是$,
$$allDirArray
${$allDirArray}
相同,
{}
是可选的(但通常推荐,如果只是为了可读性)。我个人更喜欢
$allDirArray->[$I]{dir}
。我个人觉得
${$foo}
的可读性不如
$$foo
:-)。同意
$foo->[$i]
是您将得到的最干净的。谢谢你的提示,所以!这样显式地取消引用可以消除歧义。否则,像
$$foo[1]
这样的结构在6个月内就更可能误导您,因为您不确定您的意思是
${$foo}[1]
,还是“${$foo[1]}”。更丑,我同意你;)@基诺皮科:是的,我重读了这篇文章,意识到我被搞糊涂了。最初,OP是从该数组的引用(
$allDirArray
)中声明的,这意味着他正在使用一个hashref数组的引用。无论如何,我认为@Kinopiko的观察是关于金钱的+1@Sinan:是的。当我第一次查看时,我只注意第一句话,“我有一系列匿名哈希的引用。” $ perl allarraydir.pl Global symbol "$allDirArray2" requires explicit package name at allarraydir.pl line 10. Execution of allarraydir.pl aborted due to compilation errors.
use Data::Dumper;
print Dumper($allDirArray);
use strict;
use warnings;

my $allDirArray = [ ''.{ 'dir' => 'somedir' } ];

my $tempdir = ${$allDirArray}[0]{'dir'};
# or
my $tempdir = $allDirArray->[0]{'dir'};
Can't use string ("HASH(0x8555168)") as a HASH ref while "strict refs" in use at nameOfProgram.pl line 8.