在对answer to a question about hash slices的评论中,有人想知道如何使用箭头语法通过哈希引用访问哈希切片,或许想一想
@$ref->{@keys}
会这样做的 .
是的,正确的语法是 @$ref{@keys}
或 @{$ref}{@keys}
,但这不是问题的重点 .
我试图找出带箭头的表达式所需的数据结构:
#! /usr/bin/env perl
use strict;
use warnings;
my $ref = {"a" => 1, "b" => 2, "c" => 3};
my @keys = qw/ a b c /;
#$ref = [ { a => 9, b => 8, c => 7 } ];
#$ref = [ { a => {}, b => {}, c => {} } ];
print @$ref->{@keys}, "\n";
如上所述,代码失败了
Not an ARRAY reference at ./prog line 12.
这是有道理的: @$ref
想要一个数组的引用,所以我尝试在对匿名数组的引用中包装哈希引用 . 那些尝试失败了
Can't use an undefined value as a HASH reference at ./prog line 12.
跟踪输出是
$ debugperl -Dt prog
[...]
(prog:12) pushmark
(prog:12) padsv($ref)
(prog:12) rv2av
(prog:12) rv2hv
Can't use an undefined value as a HASH reference at prog line 12.
print
行的语法转储是
$ debugperl -Dx prog
[...]
{
484 TYPE = print ===> 2
FLAGS = (VOID,KIDS)
{
485 TYPE = pushmark ===> 486
FLAGS = (SCALAR)
}
{
372 TYPE = helem ===> 371
FLAGS = (SCALAR,KIDS)
{
487 TYPE = rv2hv ===> 361
TARG = 5
FLAGS = (SCALAR,KIDS,REF)
PRIVATE = (STRICT_REFS)
{
373 TYPE = rv2av ===> 487
TARG = 4
FLAGS = (SCALAR,KIDS,REF)
PRIVATE = (STRICT_REFS)
{
486 TYPE = padsv ===> 373
TARG = 1
FLAGS = (SCALAR,MOD)
}
}
}
{
361 TYPE = padav ===> 372
TARG = 2
FLAGS = (SCALAR)
}
}
{
371 TYPE = const ===> 484
TARG = 19
FLAGS = (SCALAR)
}
}
[...]
未定义的值来自哪里? $ref
的值是什么程序正常终止?
2 回答
它无效(或至少没有意义)Perl语法 - 我有点惊讶它没有被标记为语法错误 .
我首先想到它试图在标量上下文中评估数组
@$foo
并将结果用作哈希引用,但这并没有发生 . 相反,从您发布的调试输出,它看起来更像是试图直接使用内部数组变量(AV)结构作为散列引用(RV),这是一种标量(SV;详情请参阅perlguts) .我没有查看源代码,但看起来好像
rv2hv
例程注意到自从我上次查看perl的内部结构以来已经有好几年了 . )您可能需要考虑提交错误报告 .
顺便说一句,一个更简单的测试案例,证明了这种效果只是
@foo->{bar}
.手段
所以它应该相当于
它不是,所以这是一个错误 . 它仍然存在于Perl 5.16.0的近期状态 . (v5.15.4,具体)
请使用
perlbug
命令行工具进行报告 . (只需输入perlbug
并回答几个简单的问题 . )