Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Better way to define global variables

by govindkailas (Acolyte)
on Jul 25, 2013 at 13:40 UTC ( #1046340=perlquestion: print w/replies, xml ) Need Help??
govindkailas has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, I have defined some system specific variables in a .pm file and wanted to use those variables in all the perl scripts which use the .pm. This is how my looks like
package Utilities; use Exporter; @EXPORT = ($SYS_DIR); our $SYS_DIR="/path/to/sys"; 1;
And here is the .pl file
use Utilities; use strict; print "This is the value for SYS_DIR=$SYS_DIR";

Replies are listed 'Best First'.
Re: Better way to define global variables
by choroba (Bishop) on Jul 25, 2013 at 13:44 UTC
    You do not want to export the value of the variable, but the variable itself. Use
    @EXPORT = qw($SYS_DIR);

    Also, the Exporter's documantation states a different way how to make a package use it. Change the other line to

    use Exporter 'import';
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Better way to define global variables
by Athanasius (Bishop) on Jul 25, 2013 at 14:03 UTC

    Ok, you now know how to do this. Here’s why you shouldn’t! From Exporter#What-Not-to-Export:

    Do not export variable names. Just because Exporter lets you do that, it does not mean you should.

    @EXPORT_OK = qw( $svar @avar %hvar ); # DON'T!

    Exporting variables is not a good idea. They can change under the hood, provoking horrible effects at-a-distance, that are too hard to track and to fix. Trust me: they are not worth it.

    To provide the capability to set/get class-wide settings, it is best instead to provide accessors as subroutines or class methods instead.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Better way to define global variables
by kcott (Chancellor) on Jul 25, 2013 at 14:36 UTC

    G'day govindkailas,

    It's generally not a good idea to export by default (i.e. with @EXPORT) — see the Exporter documentation sections: Selecting What to Export and What Not to Export. Instead, consider using @EXPORT_OK and %EXPORT_TAGS.

    Here's an example of that does that:

    package Utilities; use strict; use warnings; use Exporter qw{import}; my @sys_exports = qw{$SYS_DIR $SYS_OTHER}; my @util_exports = qw{$UTIL_THIS $UTIL_THAT}; our @EXPORT_OK = (@sys_exports, @util_exports); our %EXPORT_TAGS = (SYS => [@sys_exports], UTIL => [@util_exports]); our $SYS_DIR = "sys_dir"; our $SYS_OTHER = "sys_other"; our $UTIL_THIS = "util_this"; our $UTIL_THAT = "util_that"; 1;

    Here's some sample runs showing how to use it.

    No namespace pollution unless specifically requested:

    $ perl -Mstrict -Mwarnings -E ' use Utilities; say $SYS_DIR; ' Global symbol "$SYS_DIR" requires explicit package name at -e line 3. Execution of -e aborted due to compilation errors.

    Request a specific item:

    $ perl -Mstrict -Mwarnings -E ' use Utilities qw{$SYS_DIR}; say $SYS_DIR; ' sys_dir

    Request multiple items using a tag:

    $ perl -Mstrict -Mwarnings -E ' use Utilities qw{:SYS}; say $SYS_DIR; ' sys_dir

    Mix specific and tag requests:

    $ perl -Mstrict -Mwarnings -E ' use Utilities qw{:UTIL $SYS_OTHER}; say $SYS_OTHER; say $UTIL_THAT; ' sys_other util_that

    -- Ken

Re: Better way to define global variables
by davies (Prior) on Jul 25, 2013 at 14:28 UTC
Re: Better way to define global variables
by MidLifeXis (Monsignor) on Jul 25, 2013 at 13:51 UTC

    In addition to what choroba said, I am getting the same error as you are (although you didn't state it in your question, just in the CB): Global symbol "$SYS_DIR" requires explicit package name. Obviously I am missing something in the documentation. Adding strictures/warnings does not seem to help identify the problem.

    Update: The key was explicitly importing the import method with the use Exporter 'import' line. I missed it in my initial reading. Apply choroba's changes and you should be set.


Re: Better way to define global variables
by hdb (Monsignor) on Jul 25, 2013 at 14:02 UTC

    Any chance you have another lying around? Try:

    use strict; use Utilities; print $INC{''},"\n"; print "This is the value for SYS_DIR=$SYS_DIR";

    and see whether you get the correct path.

    I have no problems with your code after making choroba's proposed changes.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1046340]
Approved by marto
Front-paged by kcott
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2018-12-11 07:34 GMT
Find Nodes?
    Voting Booth?
    How many stories does it take before you've heard them all?

    Results (53 votes). Check out past polls.

    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!