Perl - 为什么我从数组引用的赋值给出了错误

时间:2017-09-30 11:01:50

标签: perl reference

下面的片段A工作,通过取消引用数组引用来复制数组。

片段B,在某些实际代码中更深层次,但不是。注释掉的行不是实际代码的一部分,它可以正常工作(%ips是一个散列,其中每个键是一个IP地址,每个值都是对数组的引用)。

但为什么注释掉的行会因消息

而失败
  

全球符号" $ ips"需要明确的包名称在...

片段A:

my $a1 = [1,2,3];
say $$a1[1];
my @a2 = @$a1;
say "@a2";

片段B:

    else {
            # Initialise count to 1, 
            # set both dates:
        $ips{$1} = [1, $2, $2];
        # my @arr = @$ips{$1};  # error...
    }

3 个答案:

答案 0 :(得分:3)

Perl正在寻找$ips变量,因为您在解除引用%ips哈希时犯了错误。你可以

my @arr = @{ $ips{$1} };

my $ref = $ips{$1};
my @arr = @$ref; # or @{ $ref }

答案 1 :(得分:2)

使用代码的问题如下:

@$ips{$1}

是你认为" @"解除引用" $ ips {$ 1}" (所以它可以分配给一个数组),但实际上该行正在使用" {$ 1}"从" @ $ ips"。

获取元素

" @"和" $" sigils比#34; {$ 1}"更紧密地绑定是的,所以上面更接近:

(@$ips) {$1}

比你想要的,是:

@ ($ips{$1})

为了解决这个问题,你可以告诉Perl拥有" @" sigil on" $ ips {$ 1}"通过推出" $ ips {$ 1}"在大括号中,像这样:

@{$ips{$1}}

通过这种方式,首先不存在歧义。

答案 2 :(得分:2)

@$ips{$1}

的缩写
@{ $ips }{$1}     # Hash slice, like @hash{"a", "b", "c"}

但你想要

@{ $ips{$1} }     # Array, like @array
Scalar         Direct           $NAME         $scalar
Scalar         By ref (simple)  $$NAME        $$scalar_ref
Scalar         By ref           $BLOCK        ${ $scalar_ref }

Array          Direct           @NAME         @array
Array          By ref (simple)  @$NAME        @$array_ref
Array          By ref           @BLOCK        @{ $array_ref }

Hash           Direct           %NAME         %hash
Hash           By ref (simple)  %$NAME        %$hash_ref
Hash           By ref           %BLOCK        %{ $hash_ref }

Hash element   Direct           $NAME{EXPR}   $hash{key}
Hash element   By ref (simple)  $$NAME{EXPR}  $$hash_ref{key}
Hash element   By ref           $BLOCK{EXPR}  ${ $hash_ref }{key}

Hash slice     Direct           @NAME{LIST}   @hash{qw( a b c )}
Hash slice     By ref (simple)  @$NAME{LIST}  @$hash_ref{qw( a b c )}
Hash slice     By ref           @BLOCK{LIST}  @{ $hash_ref }{qw( a b c )}

Array element  Direct           $NAME[EXPR]   $array[3]
Array element  By ref (simple)  $$NAME[EXPR]  $$array_ref[3]
Array element  By ref           $BLOCK[EXPR]  ${ $array_ref }[3]

Array slice    Direct           @NAME[LIST]   @array[3..5]
Array slice    By ref (simple)  @$NAME[LIST]  @$array_ref[3..5]
Array slice    By ref           @BLOCK[LIST]  @{ $array_ref }[3..5]