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

Hello,

Just a question relating to module management, I had a search around but couldn't quite find the answer I am after...

I am currently using perl alongside CVS for version control (under linux). I use CVS to maintain two copies of my scripts...stable and development. I have a set of modules (which I am developing) that accompanies my main .pl script.

Say for example, I have two directories with my two versions:

/opt/scripts/stable

/opt/scripts/development

In each directory I have a copy of my .pl script and the modules. How do I word the "use lib..." in my .pl file to make sure it includes the right set of modules?

- I initially though of using "use lib ./lib" but this only works if you are in one of the above directories. (which is not always the case!)

- I then tried to do a bit of if-else at the top of my .pl file but this didn't work (I assume the "use lib" happens before anything is executed?)

So...are modules the correct way of going about this? If so, how should I go about managing these files?

Cheers Andrew

Replies are listed 'Best First'.
Re: Perl module management
by moritz (Cardinal) on Jul 20, 2009 at 07:59 UTC
    use FindBin; use lib "$FindBin::Bin/lib";

    Should do.

    Yes, use is executed at compile time, so an if/else would require extra care (for example a string-eval) to work, or useif.

    (Chances are that somebody will step up and tell you why FindBin is a bad idea, but so far it always worked for me.)

Re: Perl module management
by Bloodnok (Vicar) on Jul 20, 2009 at 11:58 UTC
    Personally, I wouldn't/don't modify the use in-line (and wouldn't recommend it either), instead...
    • I modify both PERL5LIB and PATH to point to the development and stable libraries in that order e.g. assuming sh/ksh,export PERL5LIB=<devel>:<stable> ; export PERL5LIB=<devel>:<stable>
    • Instantiate modules/scripts in the development library when and only when, it is/they are being worked on
    In this way, the code doesn't have to change purely because development is underway - perl/the shell will pick up the appropriate module/script.

    A user level that continues to overstate my experience :-))

      This sounds like a neat idea to me. One remaining question though, how do I instantiate the correct set of libraries?

        I suspect it'll be pretty much as you are already - the major difference being in the actual usage.
        1. Set up your environment as hinted earlier i.e. as follows:
          export PERL5LIB=/opt/scripts/development/lib;/opt/scripts/stable/lib export PATH=/opt/scripts/development/lib;/opt/scripts/stable/lib:$PATH
        2. Check out the stable code into /opt/scripts/stable/lib
        3. Check out development code (into /opt/scripts/development/lib) when and only when you need to fix/enhance code
        4. In main.pl, just use module; as normal - perl will pick up the development version in preference to the stable version (because of the order in which you declared the libraries in PERL5LIB).
        5. If main.pl is to be changed, merely check out the development version - simply entering main.pl on the command line, the shell willpick up the development version.
        6. Once development work is complete and the file checked in, remove the file from the development library.
        Having said that, your way of working is unusual in as much as it is more usual to maintain only one copy of a file within the version control system - you have multiple/dual copies of files knocking about disproportionately increasing the maintenance overhead.

        I'm guessing each file is located within CVS under opt/scripts/development/lib/name.pm or opt/scripts/stable/lib/name.pm ... or maybe even development/lib/name.pm or stable/lib/name.pm.

        Far more usual would be to maintain just one copy - located under either lib/name.pm, name.pm, lib/module/name.pm or module/name.pm (the latter 2 catering for CPAN compatible directory structure) - the target root directory being set as appropriate when checking the file out (and the file being removed from the development area on check-in).

        A user level that continues to overstate my experience :-))
Re: Perl module management
by Anonymous Monk on Jul 20, 2009 at 12:31 UTC
    If you make your scripts into modules, your script can be 2 lines
    use MyScript; MyScript->run;
    then you could run using
    perl -I/opt/scripts/development -S script.pl perl -I/opt/scripts/development /opt/scripts/development/script.pl perl -Mlib=/opt/scripts/stable script.pl
    but better to write lots of tests and use make test or prove when developing. As example see tracker (App::TimeTracker).