John White John White - 3 years ago 126
Perl Question

Perl - why does my assignment from an array ref give an error

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...
}

J-L J-L
Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download