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

I am writing a small(ish) perl project for personal use. As such, for the moment at least my production version of the project will reside on the same box as development. My question is this: If I have a set of modules and perl files in a development directory, say
/home/user/Projects/Perl_mods/ModuleGroup/MyModule.pm /home/user/Projects/Perl_Project/MyProject.pl
and MyProject.pl references the module as: use ModuleGroup::MyModule How do I set up things so that if I run MyProject.pl from the development directory, it will use the development module(s), but if I run it from a release directory, it will load the module instead from a typical release directory such as /usr/local/lib/ste_perl/ModuleGroup/MyModule.pm?

Replies are listed 'Best First'.
Re: Separating Development and Release Modules
by mr_mischief (Monsignor) on Sep 10, 2007 at 00:08 UTC
    Well, one easy and straightforward way to do this is to use lib qw( devel/lib/path ); in your development copy, and delete that line in production copies.

    Another way would be to unshift into @INC (see perlvar) in a BEGIN block. The following code puts './lib' at the head of the line for module searches if $devel is true, and does nothing if it is false. This lets you tie other things to the same variable if needed, so you only change it in one place.

    BEGIN { my $devel = 0; if ( $devel ) { unshift @INC, qw( ./lib ); } }

    You could also conditionally require a module and then call its import method/sub. This can be done outside a BEGIN block, since require() happens later than does use().

    Finally, there are advanced options that have to do with playing tricks with @INC (like putting coderefs in it and such), but those are probably best left alone until you have a solid grasp of other ways to conditionally require a module.

Re: Separating Development and Release Modules
by pajout (Curate) on Sep 10, 2007 at 12:01 UTC
    Primarily, consider cvs or svn or something similar to keep your versions of projects and libraries. Though it is not necessary, it is widely recommended.

    I suppose you want to have two separated locations, one for libraries and one for project-specific files. In this situation, with respect of your need to have productional and development versions, I can see following directory structure:

    ~/projects/productional/perl-lib ~/projects/productional/project1 ~/projects/development/perl-lib ~/projects/development/project1
    The other idea is how to use proper libraries? In your project scripts, you can do something as

    #standard modules use FindBin (); #to add proper dir: FindBin::again(); use lib $FindBin::RealBin.'/../perl-lib'; #internal modules use MyLibraryModule;
    It causes usage of development library in development scripts and productional library in productional scripts. The last issue is How to change devel version to productional one? If you will use some versioning system, it will support it easily. Without versioning system, it is up to your head and hands to copy files in the right way.
Re: Separating Development and Release Modules
by Fletch (Bishop) on Sep 10, 2007 at 13:05 UTC

    Have your shell setup a different environment (i.e PERL5LIB) for the development and production paths. The "production" path should only have that version, while the "development" version points first to your project directories then the production one (so that the development versions take precedence, but it'll fall back to the live ones if you don't have something present in development). You can do this either with shell functions, or take a look at Envy for a little fancier utility.