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

Hi I have a global variable declared and initialized in my .pl file and I am also using this variable in one or more of my .pm files. How do I package this global variable(s) in order to avoid the warnings when run with use strict. The error is Variable "%line" is not imported at ./../bin/myfile.pl line 19. Global symbol "$time" requires explicit package name at ./../bin/file.pl line 64. This error is in mod1.pm Global symbol "%line" requires explicit package name at ../bin/mod1.pm line 55. What package has to used and how? Thanks and Regards, Syed

Edit by castaway - Moved to Seekers of Perl Wisdom from Perlmonks Duscussion

Replies are listed 'Best First'.
Re: Usage of global variables
by BUU (Prior) on Jan 04, 2005 at 07:08 UTC
    You may refer to properly declared globals in your "pl file" as $main::variable. main is the default name space, unless changed by a package statement.
Re: Usage of global variables
by Thilosophy (Curate) on Jan 04, 2005 at 07:39 UTC
    You can probably access your global %line as %main::line. Another (better) way would be to declare them with our:
    our %line = ( 1 => 2, 3 => 4 );
    However, if you really want to use global variables, you should put them into some namespace other than the default, for example like so:
    %MyGlobals::line = ( 1 => 2 , 3 => 4 );
    or so
    { package MyGlobals; our %line = ( 1 => 2 , 3 => 4 ); }

    Try one of these, dropping use strict; is not a good idea..

Re: Usage of global variables
by jbrugger (Parson) on Jan 04, 2005 at 07:10 UTC
    It would be an idea to read about the different variable types, like lexial, local, module varables, etc.
    It's all here.
Re: Usage of global variables
by johnnywang (Priest) on Jan 04, 2005 at 09:10 UTC
    I also have a similar situation where I have many such constants (e.g., port numbers, database parameters, directory names) that are used by several modules and scripts. I usually create a module called Constants.pm, which contains all the constants:
    # Constants.pm package Constants; use strict; use Exporter; our @ISA = qw(Exporter); # if you want to automatically import our @EXPORT = qw(%ABC $A); # or if you want to explicitly import our @EXPORT_OK = (); our $A = "A"; our %ABC = ("A"=>1,"B"=>2,"C"=>3); 1;
    You can then just "use Constants" in other modules and scripts.
      Thanks for all those comments. I have done it but i dont know how i have written the code somehow like this: The hash used here is just the declaration, it is defined dynamically.
      use strict; use vars qw(%line $time); use mod1 qw(%line); use mod2 qw(%line $time);
      in the main .pl file and in the .pm files it is like this
      use strict; use Exporter(); use vars qw(%line);
      in the mod1.pm, and
      use strict; use Exporter(); use vars qw(%line $time);
      in mod2.pm. Can any one explaing why and how is it working without giving any warnings.

      2005-01-04 Janitored by Arunbear - added code tags, as per Monastery guidelines

        You aren't getting warnings, but you aren't getting what you think you are here. It would help to see more code, and please use code tags. The first problem is that you weren't really exporting.
        package mod1; use strict; use vars qw(%line); use Exporter(); # The next two lines are vital for exporting. our @ISA = qw(Exporter); our @EXPORT_OK = qw(%line); BEGIN { %line = (this => "line"); } 1;
        package mod2; use strict; use vars qw(%line $time); use Exporter(); # Same with this one. our @ISA = qw(Exporter); our @EXPORT_OK = qw(%line $time); BEGIN { %line = (that => "line2"); $time = time(); } 1;
        You have one more problem. By exporting the same name in two modules, you will be clobbering your first one.
        use strict; use vars qw(%line $time); use mod1 qw(%line); use mod2 qw(%line $time); # This will print: # that,line2 print join(",",%line),"\n";
        If you really want both packages to have their own global named %line then don't export them. Use them with package names, like this: %mod1::line.
Re: Usage of global variables
by CountZero (Bishop) on Jan 04, 2005 at 07:20 UTC
    Difficult to answer without seeing any code, but it seems you have the structure of your scripts and modules and their variables in a mess. Try to avoid the use of global variables; esp. global variables which need to span separate scripts and modules in order to make your program work: it is almost always a bad idea.

    And if you cannot change things, just drop use strict. It does not give any other benefit than showing you possible problems in your program. If you are aware of these, you can as well drop it (at your own risk).

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Usage of global variables
by sasikumar (Monk) on Jan 04, 2005 at 11:05 UTC