我正在和一些使用哈希引用的Perl搏斗。
最后我发现我的问题就在于:
$myhash{$key} |= {};
即“分配$ myhash {$ key}对空哈希的引用,除非它已经有一个值”。
取消引用它并尝试将其用作哈希引用,导致使用字符串作为哈希引用的解释器错误。
将其更改为:
if( ! exists $myhash{$key}) {
$myhash{$key} = {};
}
......让事情奏效。
所以我没有问题。但我很好奇发生了什么。
任何人都可以解释一下吗?
答案 0 :(得分:16)
Perl有速记赋值运算符。 ||=
运算符通常用于设置变量的默认值,因为Perl的逻辑运算符返回最后一个值。问题是您使用的是|=
按位或代替||=
,这是逻辑或。
从Perl 5.10开始,最好使用//=
。 //
是逻辑定义的或运算符,并且在定义当前值但是为false的极端情况下不会失败。
答案 1 :(得分:15)
您看到使用字符串作为哈希引用的错误的原因是因为您使用了错误的运算符。 |=
表示“按位或分配”。换句话说,
$foo |= $bar;
与
相同 $foo = $foo | $bar
您的示例中发生的事情是您的新匿名哈希引用正在进行字符串化,然后使用$myhash{$key}
的值进行按位或运算。为了进一步混淆问题,如果当时未定义$myhash{$key}
,则值是哈希引用的简单字符串化,类似于HASH(0x80fc284)
。因此,如果您对结构进行粗略检查,它可能看起来像<哈希引用,但事实并非如此。以下是Data::Dumper
的一些有用输出:
perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
$VAR1 = {
'foo' => 'HASH(0x80fc284)'
};
以下是使用正确运算符时的结果:
perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
$VAR1 = {
'foo' => {}
};
答案 2 :(得分:4)
我认为您的问题是使用“|=
”(按位或分配)而不是“||=
”(如果为false则分配)。
请注意,您的新代码并不完全等效。不同之处在于“$myhash{$key} ||= {}
”将使用哈希引用替换现有但错误的值,但新值不会。在实践中,这可能不相关。
答案 3 :(得分:2)
试试这个:
my %myhash;
$myhash{$key} ||= {};
据我所知,你不能在my
子句中声明哈希元素。首先声明哈希,然后在中添加元素。
编辑:我看到你已经取出了my
。如何尝试||=
代替|=
?前者是“懒惰”初始化的惯用语。