首页 文章

什么是@ $ ref - > {@ keys}试图访问?

提问于
浏览
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 的值是什么程序正常终止?

2 回答

  • 8

    它无效(或至少没有意义)Perl语法 - 我有点惊讶它没有被标记为语法错误 .

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

    我没有查看源代码,但看起来好像 rv2hv 例程注意到自从我上次查看perl的内部结构以来已经有好几年了 . )

    您可能需要考虑提交错误报告 .

    顺便说一句,一个更简单的测试案例,证明了这种效果只是 @foo->{bar} .

  • 5
    @$ref->{@keys}
    

    手段

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

    所以它应该相当于

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

    它不是,所以这是一个错误 . 它仍然存在于Perl 5.16.0的近期状态 . (v5.15.4,具体)

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

相关问题