1

Fragment A below works, copying an array by dereferencing an array ref.

Fragment B, deeper in some real code, does not. The commented-out line is not part of the real code, which works fine (%ips is a hash in which each key is an IP address and each value is a reference to an array).

But why does the commented-out line fail with the message

Global symbol "$ips" requires explicit package name at ...

Fragment A:

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

Fragment B:

    else {
            # Initialise count to 1, 
            # set both dates:
        $ips{$1} = [1, $2, $2];
        # my @arr = @$ips{$1};  # error...
    }
1
  • Greatly obleeged to the answerers, {$ips{$1}}; works fine. But I'm puzzled that ($ips{$1}); (round instead of curly) fails. I'll try to find out why by RTFM...:-) @J-L Commented Oct 2, 2017 at 12:13

3 Answers 3

3

Perl is looking for $ips variable as you've made mistake when dereferencing %ips hash. You can

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

or

my $ref = $ips{$1};
my @arr = @$ref; # or @{ $ref }
Sign up to request clarification or add additional context in comments.

Comments

2

The problem with using code like:

@$ips{$1}

is that you think that "@" is dereferencing "$ips{$1}" (so it can be assigned to an array), but in reality that line is using "{$1}" to get an element from "@$ips".

The "@" and "$" sigils bind more tightly than "{$1}" does, so the above is closer to:

(@$ips) {$1}

than what you want, which is:

@ ($ips{$1})

To overcome this, you can tell Perl to have the "@" sigil work on "$ips{$1}" by putting "$ips{$1}" in curly brackets, like this:

@{$ips{$1}}

This way, there's no ambiguity over which happens first.

Comments

2
@$ips{$1}

is short for

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

but you want

@{ $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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.