Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Global symbol requires explicit package name

Tags:

perl

strict

I am trying to store my log messages in a hash depending upon message type as shown below:

#!/usr/bin/perl

use strict;
use warnings;

my %log;

opendir (DIR, '.') or die $!;
while (my $file = readdir(DIR)) {
    # some code to select TAR filename in $1
    if (-e $1.'.tar') {
        push(@{$log->{$1}}, $file); /* line 12 */
    }
    else {
        $log{$1} = [];
        push(@{$log->{$1}}, $file); /* line 16 */
}

Now this code gives compilation error saying:

Global symbol "$log" requires explicit package name at at lines 12 & 16

where I am actually trying to use the hash "%log". What can be a possible way to get rid of this error ? Why exactly is this happening ?

I did see some explanation on context where people replied saying the variables were created in one context and were being referred in another but I feel this variable should be available inside while loop in this piece of code. This happens only when I have "use strict" and works fine otherwise.

I have started with Perl so I do not fully understand the basics! Please help me understand why this variable is not accessible.

like image 680
i01000001 Avatar asked May 01 '13 16:05

i01000001


2 Answers

my %log;

defines hash %log, but lines 12 and 16 don't use it. Instead, you're accessing the anonymous hash referenced by the scalar $log which you've never declared. You have two options.

  • You could continue to use an anonymous hash.

    my $log = {};   # The creation of the hash ("{}") is currently being done
                    # implicitly by "->". This is called autovivification.
    
    
    ... $log->{...} ...
    

    This adds a bit of a extra complexity and an unnoticeable reduction in speed.

  • You could use use a hash directly.

    my %log;
    
    ... $log{...} ...
    
like image 195
ikegami Avatar answered Nov 19 '22 03:11

ikegami


I'm not sure what are you trying to do with $1, but the hash access is not a reference, so change:

$log->{$1}

to

$log{$1}

The error message you got, says: Global symbol "$log" requires explicit package, because $log variable was not defined. Remember that %log and $log are two different variables (hash vs scalar).

like image 32
Miguel Prz Avatar answered Nov 19 '22 02:11

Miguel Prz