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

Magnificent Monks!

This is a beginner question. I'm in the process of trying to clean up a Perl module I wrote that defines several variables that are used commonly by several scripts (e.g. things like $path_to_log_dir, $path_to_my_exe, @array_of_common_things, etc). Currently: The scripts work fine, but because of what I have been learning on perlmonks, I know that I really need to clean this up.

Here is what I plan to do:
  1. add "use strict" to module and all scripts
  2. use a package declaration in the module
  3. export all subs in module with @EXPORT_OK
Here is my question: for the common variables mentioned earlier, what is the best way to make them available to the scripts? Should I declare them as "our" variables, or should I just create a subroutine in the module and pass copies of the variables to the scripts by way of the subroutine, or would something else be better?

I am grateful for any help/suggestions you could offer.


Thank you,
memnoch
  • Comment on How to make Common Variables defined in Module available to Scripts

Replies are listed 'Best First'.
Re: How to make Common Variables defined in Module available to Scripts
by wfsp (Abbot) on Dec 06, 2007 at 15:47 UTC
      Nothing to read here.

      Thanks wfsp! I just took a look, and it seems like a great resource!

      memnoch

Re: How to make Common Variables defined in Module available to Scripts
by shmem (Chancellor) on Dec 06, 2007 at 15:50 UTC
    Should I declare them as "our" variables, or should I just create a subroutine in the module and pass copies of the variables to the scripts by way of the subroutine, or would something else be better?

    Either is ok, but which is best depends solely on the purpose of the modules and the data encapsulation that is required. Are the variables read-only? would setting the variables to some value have nefarious consequences? are they subject to security concerns?

    There are many ways to do what you are after, e.g. have a look at the Config.pm code for an implementation of a read-only hash.

    Rules of thumb:

    • use lexical variables in the Module if you need to restrict the access of a variable, and dish out its content via a subroutine.
    • don't reach into the caller's namespace from within a module.
    • for best results, in scripts that use a module, use a package's variables with their fully qualified name rather than copying the typeglob / assigning to the current package's typeglob.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Thanks shmem! Indeed, the variables are read-only, and resetting them would not be good (though, to be sure, security is not a high concern here). I'll take a look at the link you suggested. Also, I found the following CPAN module for creating read-only scalars, arrays, hashes. Looks useful, but probably overkill for what I'm doing.

      memnoch

      Gloria in Excelsis Deo!
        Have a look at the standard module constant, too. It's not as flexible as Readonly, but not as dangerous, either.

        I wouldn't worry too much about the occasional downvote: maybe someone has clicked on the wrong button or his breakfast-egg was not boiled to perfection or whatever.

        However, some may say that it is better style to update the original question-node with your comments (if they still pertain to the original question) and insights learned through studying the Monks' answers.

        Simple "Thank you!" nodes are frowned upon by many as they don't add to the discussion and may elicit cries of "XP-whoring". It is perhaps better to express your gratitude for the wisdom received by a ++ vote and a private message of thanks.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: How to make Common Variables defined in Module available to Scripts
by rpanman (Scribe) on Dec 06, 2007 at 15:54 UTC
    Not specifically answering your question but you might want to consider reading "Perl Medic: Maintaining Inherited Code" by Peter Scott which deals with many of the issues of updating legacy code (whether inherited or written by yourself in a previous life). Certainly helped me clean up a load of my code and has prevented many of the "what did I mean when I wrote that?" moments. Just a thought...
      Nothing to read here.

      Thanks rpanman....that book looks interesting! Thanks for the tip! For those interested, a like to the above book is here.

      memnoch

Re: How to make Common Variables defined in Module available to Scripts
by jrsimmon (Hermit) on Dec 06, 2007 at 16:12 UTC
    My approach to this same problem a year or so ago was to create a package "Common" that exported the common variables I use on a regular basis. Now all my perl scripts begin like
    use strict; use warnings; use Common qw($common1, $common2, ..., $commonN);

    This approach provided the opportunity to create (ie, learn how to) my first package and has been a very intuitive solution.
      Nothing to read here.

      Thanks jrsimmon.....I'll probably do something like that!

      memnoch

Re: How to make Common Variables defined in Module available to Scripts
by sh1tn (Priest) on Dec 06, 2007 at 16:03 UTC
    Some languages allow access to class, object and even class level instance variables, but IMHO the best way is to use class methods (getters/accessors) for getting variables if they are not object attributes. And if they are, use instance accessor methods.

    Class::MethodMaker, Class::BuildMethods.


Re: How to make Common Variables defined in Module available to Scripts
by ropey (Hermit) on Dec 06, 2007 at 17:02 UTC

    I generally steer towards using a 'Constants' package for such things.

    package SUP::ServerConstants; use strict; use vars qw/@EXPORT @EXPORT_OK/; require Exporter; use base qw/ Exporter /; use Data::Dumper; @EXPORT = qw/SERVER_NAME MYSQL_PORT SERVER_ID/; @EXPORT_OK = qw/HTTP_PROXY PATH_TO_BINARIES/; use constant SERVER_NAME => 'http://FOO'; use constant MYSQL_PORT => '3308'; use constant SERVER_ID => '44'; use constant HTTP_PROXY => ''; use constant PATH_TO_BINARIES = '/var/foo';

    Then to access them in your script you would have something like...

    #!/usr/bin/perl -w use strict; use SUP::ServerConstants qw/PATH_TO_BINARIES/; print PATH_TO_BINARIES;