JDS
JDS

Reputation: 16988

Perl modifying hash in subroutine - global symbol requires explicit package name

Having some trouble adding some keys to a hash, i.e. modifying in a subroutine. Here's my subroutine call:

getMissingItems($filename, \%myItems); #myItems is already defined above this

and the subroutine itself:

sub getMissingItems {
    my $filename = shift;
    my $itemHash = shift;

    #... some stuff

    foreach $item (@someItems) {

        if (not exists $itemHash{$item}) {
            %$itemHash{$item} = 0; 
        }

    }

}

I get the error "Global symbol %itemHash requires explicit package name"

How should I be doing this properly? Thanks.

EDIT - thanks everyone, over this first hurdle. I'm now getting "Can't use string ("0") as a HASH ref while "strict refs" in use." I just want to set the missing key entry to zero

Upvotes: 1

Views: 3050

Answers (5)

ikegami
ikegami

Reputation: 385917

There is no %itemHash in scope of your sub, yet you try to use a variable named that.

You mean to access the hash referenced by $itemHash, so

if (not exists $itemHash{$item}) {
    %$itemHash{$item} = 0; 
}

should be

if (not exists $itemHash->{$item}) {
    $itemHash->{$item} = 0; 
}

By the way, you could simplify that to

$itemHash->{$item} //= 0; 

(That checks if the element is defined, not if it exists, but that's probably the same thing in this case.)

Upvotes: 1

Robert Hanson
Robert Hanson

Reputation: 579

Your code has $itemHash{$item}, it should be $itemHash->{$item}. The code below points to the line with the error.

sub getMissingItems {
    my $filename = shift;
    my $itemHash = shift;

    foreach $item (@someItems) {

        if (not exists $itemHash{$item}) { # <--- this is wrong
            %$itemHash{$item} = 0; # <--- this one too
        }

    }
}

Upvotes: 1

hobbs
hobbs

Reputation: 240010

The line %$itemHash{$item} = 0; should read $itemHash->{$item} = 0;. The version you have tries to do something different (and wrong). For help untangling references, I recommend reading the Perl References Tutorial.

Upvotes: 1

choroba
choroba

Reputation: 241918

To acces a value in a hash reference, use the arrow dereference operator:

if (not exists $itemHash->{$item}) {
    $itemHash->{$item} = 0;
}

Upvotes: 1

Ryan C. Thompson
Ryan C. Thompson

Reputation: 42020

You're not using the correct syntax for accessing elements of a hashref.

Try $itemhash->{$item} or $$itemhash{$item} in the innermost loop.

Upvotes: 3

Related Questions