2011-11-16 27 views
10

在上一个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的值是否正常终止?

回答

8

这是无效的(或至少没有意义)Perl语法—我有点惊讶它没有被标记为语法错误。

我首先想到的是它试图评估标量上下文中的数组@$foo,并将结果用作哈希引用,但这看起来不太像是发生了什么。相反,从发布的调试输出看,它更像是试图直接使用内部数组变量(AV)结构作为散列引用(RV),这是一种标量类型(SV;请参阅perlguts了解详细信息)。

我还没有看过源代码,但它看起来好像rv2hv例程要么注意到它被给出了错误的结构类型并返回null,或者只是试图使用AV作为RV并实现相同这种方式的效果。 (对不起,如果听起来有点混乱,我上次查看perl的内部已经有几年了。)

你可能要考虑提交一个bug报告。

顺便说一句,一个简单的测试案例,演示效果只是@foo->{bar}

+0

它是有效的(即使没有意义),因此它不应该是语法错误。不过,这应该是一个严格的错误。 – ikegami

5
@$ref->{@keys} 

意味着

scalar(@$ref)->{@keys} 

所以它应该是相当于

my $ref2 = @$ref; 
$ref2->{@keys} 

它不是,所以这是一个错误。它仍然存在于将成为Perl 5.16.0的近期状态中。 (v5.15。4,具体)

请使用perlbug命令行工具报告。 (只需输入perlbug并回答几个简单的问题。)

相关问题