Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Trying to create a common "variable library"

by tbblake (Initiate)
on Jul 20, 2010 at 19:08 UTC ( #850492=perlquestion: print w/replies, xml ) Need Help??
tbblake has asked for the wisdom of the Perl Monks concerning the following question:

I just wrote a large set of perl scripts for a personal project. To avoid my own typoes and what not I've gotten into the habit of using "use warnings;" and "use strict;" along the way. So now that I'm done...I've found that I have a dozen or so "common" variables in the scripts that whenever I change in one, I need to change in the others. I'd like to go back into them, delete the "my" declarations in all of them, and just drop them into a common script. I know there are such methods as creating modules, and reaching into the module's namespace for variable values, but that would be a major re-write. In the end I want to do as little re-coding as possible. I'm hoping for something as simple as a "require" or "use" statement can just replace a block of variables at the top of the script. Any ideas?
  • Comment on Trying to create a common "variable library"

Replies are listed 'Best First'.
Re: Trying to create a common "variable library"
by almut (Canon) on Jul 20, 2010 at 19:37 UTC

    The low-tech solution would be

    # the "variable library", e.g. use vars qw($scalar @array %hash); $scalar = "Foo"; @array = qw(Foo Bar); %hash = (Foo => "Bar"); 1;
    #!/usr/bin/perl -l use strict; use warnings; use MyVars; print $scalar; print "@array"; print "$_ => $hash{$_}" for keys %hash;

    The ugly thing is (why I called it low-tech) that you have to mention all variables twice (because of the use vars) — but for "a dozen" variables this should be doable.

      use vars qw($scalar @array %hash);
      % perldoc vars
      NOTE: For variables in the current package, the functionality provided by this pragma has been superseded by "our" declarations, available in Perl v5.6.0 or later. See "our" in perlfunc.
      It's only a few more words to make a proper MyVars module out of it.
      package MyVars; our @ISA = qw(Exporter); our @EXPORT = qw($scalar @array %hash); [...]
        ... the functionality provided by this pragma has been superseded by "our" declarations ...

        The thing is that the extra file implies a separate lexical scope, so you can't use our (without additional hoops), because its effect is lexically scoped.  Even if the docs call use vars "superseded", it still has its occasional uses, because the functionality isn't the same as "our" in every respect.

        In the particular case of what the OP wants to use this for (i.e. having some common variable definitions to be included in several scripts), I don't really see an advantage of creating a "proper" module as you call it, i.e. putting the global variables in a different namespace first, only to then alias them all into the current package using Exporter.  As long as there's nothing else in the module, where's the benefit?

      Use do rather than require (via use) when the "module" doesn't have a package statement.

        It's maybe worth noting that the do would need to be put in a BEGIN block to have it execute at compile time

        BEGIN { do "" }

        And for anyone unsure what the difference is:  in contrast to require, do doesn't keep track of what's already been loaded — which could make a difference if you use MyVars several times (in different namespaces) in the same script/program.

      Perfect, my module-foo has never been that good since I'm more of a unix SA who uses perl to do his job, than a perl programmer. Thanks!!
Re: Trying to create a common "variable library"
by oko1 (Deacon) on Jul 20, 2010 at 23:16 UTC

    The perhaps-even-lower-tech way to go is a "do" statement. Create a file in which you define all your vars (e.g., ".myapprc"):

    $foo = "Foo"; @bar = qw/B a r/; %blah = ( b => 'l', a => 'h' );

    Then, just "load it up" in your script:

    #!/usr/bin/perl -w use strict; our($foo, @bar, %blah); do "xyzrc" or die "xyzrc: $!\n";

    I use this quite a lot, usually with a little more error checking (see "perldoc -f do"), in CGI scripts that need to source external info (database/table names, etc.)

    "Language shapes the way we think, and determines what we can think about."
    -- B. L. Whorf
Re: Trying to create a common "variable library"
by wfsp (Abbot) on Jul 21, 2010 at 06:02 UTC
    Call your "common" variables configuration and use, say, Config::Simple.
Re: Trying to create a common "variable library"
by ambrus (Abbot) on Jul 21, 2010 at 12:43 UTC

    Export those variables from a module.

    Eg., have a common module that says something like (untested):

    use warnings; use strict; package Foo::Common; use Exporter; push our @ISA, Exporter::; push our @EXPORT, qw" %red %green @blue %yellow $brown $purple "; our %red = ("foo", "bar");

    and then use this module from all other modules by saying

    use Foo::Common;
    which will import %red and all the other variables to your package.

    You can then refer to these variables even if strict is on, as if you have declared them with use vars, only they refer to the respective variables from the common package. It also does not matter whether you set the values of those variables from the common package or some other package, just make sure you don't try to use their values before you initialize them.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://850492]
Approved by Corion
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2018-03-20 02:55 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (247 votes). Check out past polls.