http://www.perlmonks.org?node_id=404794

v_o_i_d has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I'm having this problem that I find very confusing, but which (I'm certain) has an easy answer which I can't find specifically addressed in the Q&A section or elsewhere.

Basically I have a perl library (.pl) file. In it I declare a global variable our $var to be used in other modules via require etc. I also use strict; and use warnings;. In my perl module (.pm) this warning appears when I start using the 'global' variable: Global symbol "$var" requires explicit package name...

When I remove the use strict this error does not appear, but I suspect that the problem remains. Am I right in believing the $var variable is being re-declared in the perl module or has it become local to the perl module file, and the declaration our $var in the perl library file is ignored?

All I want to do is use the straight $var in other files and for $var to act like a true global variable.

simple code mock-up:

#-----file1.pl----- use strict; use warnings; our $var = 1; #------------------ #-----file2.pm----- use strict; use warnings; require 'file1.pl'; $var = 2; # <-- This doesn't work, but it is supposed to be global, + right? #------------------

Replies are listed 'Best First'.
Re: strict/warnings interference with global declarations
by revdiablo (Prior) on Nov 03, 2004 at 00:43 UTC

    You need to declare the variable with our in file2.pm as well. Note that if file2.pm had a package statement, that would cause an additional problem. But since your example doesn't, I won't cloud the issue further. :-)

    Update: if you're looking for a bit more explanation, then you should know that our does not actually create a global variable, because that doesn't need to be done.

    Package variables can be used at any time, they don't need to be declared at all. You can get access without our by fully-qualifying the package name, e.g. $main::var or $::var (which is just shorthand for the same thing). When you use our, it merely creates an alias to the package variable, so you don't have to fully qualify it. But that alias is not global, it is lexically scoped. Since file boundaries create new lexical scopes, the alias is not available from file2.pm.

Re: strict/warnings interference with global declarations
by davido (Cardinal) on Nov 03, 2004 at 00:56 UTC

    require is a runtime feature. strict does a compiletime check. Since file2 used $var, but $var is declared in file1, and since file1 isn't 'loaded' until runtime, there's no way for strictures to know, when Perl compiles file2.pm, that $var was declared in file1. So you get a compiletime error.

    Keeping track of what order things happen in, helps to figure out what's going wrong. Here's a quick rundown of the sequence of events:

    1. Perl compiles file2.pm with 'use strict' on.
    2. Perl discovers that you're using $var in file2.pm, but hasn't yet loaded file1.pl. Strict complains.

    If you had put our $var;, or use vars qw/$var/; in file2.pm, strict wouldn't complain, and you'll be ok, so long as file1.pl isn't a different package.


    Dave