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

I'm working a script that needs to have a couple of global variables that subroutines can make use of without having them passed in as arguments. Unfortunately, for reasons beyond my control, I also need to "use strict;". Is there a way that I can declare certain variables global even though I'm using strict?

Replies are listed 'Best First'.
Re: Globals with Strict
by broquaint (Abbot) on Sep 12, 2003 at 14:50 UTC
    You have three options

    1. the vars pragma to declare package level variables
    2. available in perl5.6+, our which declares a package level and also creates lexical variable aliased to the package variable
    3. fully qualify the variables with their package name

    Which you can implement like so

    use vars '$config'; our $config; $Your::Package::config;

    HTH

    _________
    broquaint

      File-scoped lexicals are globally-scoped to anything in that file. our is only really useful when dealing with application-globals - things that will be used in more than one file. (@ISA, @EXPORT_OK, and $VERSION come to mind.) That's the reason why my is singularly possessive and our is plurally possessive. I personally think that our is misused in 99% of its usage.

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Globals with Strict
by tcf22 (Priest) on Sep 12, 2003 at 14:49 UTC
    If they are in the same file using my will work, as long as it isn't in an enclosing block.
    my $i = 10; &print_i; sub print_i{ print "$i\n"; }
    If they aren't in the same file then our is the way to go
    File1:
    our $i = 10; ....
    File2:
    our $i; ... sub print_i{ print "$i\n"; }

    - Tom

Re: Globals with Strict
by cchampion (Curate) on Sep 12, 2003 at 15:06 UTC

    Others have told you to declare the shared variable at the top of the file. Here's why:

    #!/usr/bin/perl use warnings; use strict; x(); # this will trigger a warning my $shared = 'abc'; sub x { print "\$shared is: <$shared>\n"; } x(); # this will work fine

    Although $shared is within the same scope as the sub x, its value has not yet been initialized. Therefore, the first time you call the subroutine, you get a warning for using an uninitialized value. Once the program flow passes over the shared point, everything it's OK. That was why, if you need a shared value, it should be "at the top".

    HTH

Re: Globals with Strict
by bear0053 (Hermit) on Sep 12, 2003 at 14:49 UTC
    there are several ways to solve this. You can mark some variables as our.
    our $var = whatever;
    That will make it global and comply with strict. Or you can setup your functions to take in parameters
    my $var1 =5; &func1($var1); ........somewhere else in code your func dec sub func1 { #this will grab the variable $var1 you passed in my $private_var = shift; }
Re: Globals with Strict
by hardburn (Abbot) on Sep 12, 2003 at 14:52 UTC

    Declare them as my at the top of the file. our will also work, but is generally the wrong thing to do (our is what your variables are declared as by default when you're not using strict).

    If they're constants (and I certainly hope they are), you can use the constant progma instad:

    use constant FOO => 1; use constant BAR => 2;

    Though this won't interpolate within a string.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Globals with Strict
by ViceRaid (Chaplain) on Sep 12, 2003 at 14:51 UTC

    It depends what package your subroutines are living in. Assuming they're living in the main:: package, you can declare package scoped variables there by using:

    use vars qw($foo @bar %baz);

    Take a look at arturo's tutorial on variable scoping for some more ideas./

    cheers
    ViceRaid

Re: Globals with Strict
by Abigail-II (Bishop) on Sep 12, 2003 at 14:55 UTC
    Global doesn't contradict the use of use strict. Global only means "having a large scope". There are several ways of dealing with this. If all the subroutines, and any other code that needs to touch this variable are in the same file, you can just put a my $variable at the top of the file. Otherwise, you need to use a package variable. Either use the package name in combination with the variable name, or introduce the variable with use vars or our, and strict will be happy.

    Or you could just put a no strict before the code that accesses the variable.

    Abigail

Re: Globals with Strict
by jdtoronto (Prior) on Sep 12, 2003 at 14:50 UTC
    Certainly!

    Just declare them like this:

    .. .. use strict; my $globalvariable; # your code continues here #
    What it really says is declare the variables in your MAIN block and they are globally visible.

    jdtoronto