Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

dynamically loading modules/maintaining dev v. prod modules

by christopherbarsuk (Acolyte)
on Jul 28, 2001 at 02:56 UTC ( [id://100475]=perlquestion: print w/replies, xml ) Need Help??

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

I've tried a gazillion different ways of doing this, none with very much success. Surely, there must be a way, and surely there are people doing similar things out there...

Background: I maintain a set of CGI scripts which use a bunch of perl modules. Each module is kept in two different places -- production vs. development. The CGI scripts are also kept in two different places (prod vs. dev).

I want to do something like this:

if( index( $ENV{SCRIPT_NAME}, '/dev/' ) == -1 ) { use lib "/blah/perllib/"; } else { use lib "/blah/perldev/"; }

so that if the CGI script is being called from a DEV environment, it will load the DEV modules; if the script is called from a PROD environment, it will load the PROD modules. This way, my CGI scripts can be identical (even though they're kept in two separate directories).

The method above isn't working, however, presumably because the 'use' pragma is evaluated at compile time, before $ENV has a value.

What other tricks are there whereby I might accomplish what I'm after? Basically, I want my source files to load the appropriate modules depending on where they're located...

Any thoughts?

--christopher@barsuk.com

Replies are listed 'Best First'.
Re: dynamically loading modules/maintaining dev v. prod modules
by wog (Curate) on Jul 28, 2001 at 03:16 UTC
    How you're trying to do this will not work, with or without a BEGIN block. use is evaluated at compile time, and both use libs in that code fragment will need to be compiled, and thus will be executed. Other ways:

    use lib (index($ENV{SCRIPT_NAME},'/dev/') == -1) ? "/blah/perllib/" : "/blah/perldev/"; # -- or -- BEGIN { require lib; if ( index( $ENV{SCRIPT_NAME}, '/dev/' ) == -1 ) { lib->import("/blah/perllib/"); } else { lib->import("/blah/perldev/"); } } } # -- or -- BEGIN { if (index( $ENV{SCRIPT_NAME}, '/dev/' ) == -1 ) { unshift @INC, "/blah/perllib/"; } else { unshift @INC, "/blah/perldev/"; } } }
Re: dynamically loading modules/maintaining dev v. prod modules
by traveler (Parson) on Jul 28, 2001 at 18:59 UTC
    All I can think of for you to do is to use realative paths. If you structure your environments such that use lib "../libs/" refers to the proper place w.r.t. either development or live, the script should compile correctly.

    Consider this (sideways) directory tree

    perl-code live exec libs devel exec libs
    Since you are not relying on run-time vars to decide the location, I think this might solve the problem.

    --traveler

Re: dynamically loading modules/maintaining dev v. prod modules
by PrakashK (Pilgrim) on Jul 28, 2001 at 03:01 UTC
    Try putting that code in a BEGIN block:
    BEGIN { if( index( $ENV{SCRIPT_NAME}, '/dev/' ) == -1 ) { use lib "/blah/perllib/"; } else { use lib "/blah/perldev/"; } }
    Update: My apologies too. Should have tested it before posting. As wog said in the node below the code above won't work, since both use lines would be run at compile time. All my votes go to wog. Thanks.
Re: dynamically loading modules/maintaining dev v. prod modules
by HyperZonk (Friar) on Jul 28, 2001 at 03:01 UTC
    Enclose your code above in a BEGIN block. It will be evaluated at compile-time.

    Update: Drat! Beaten to the punch again!

    Update 2

    Well, I'll be snookered! I wasn't sure about that behavior (though I should know to trust wog by now), because BEGIN also runs at compile time, but I tested it and indeed, it is so! My most humble apologies and wog++.

    -HZ
Re: dynamically loading modules/maintaining dev v. prod modules
by John M. Dlugosz (Monsignor) on Jul 29, 2001 at 00:26 UTC
    You can push a sub onto @INC, not just a string. Do that with use lib. When it's called, it can examine the SCRIPT_NAME and do any complex searching logic as desired.

    —John

      This sounds interesting if a little obfu-ish. Sadly I can not get a sub put on @INC to execute

      > perl -mlib="sub{\$x=10}" -le'BEGIN{print "x=",$x++};\ use FindBin;\ print "x=$x"; print join $/,@INC' x=0 x=1 sub{$x=10} /local/lib/perl /usr/local/lib/perl5 /usr/opt/perl5/lib/5.8.0/aix-thread-multi /usr/opt/perl5/lib/5.8.0 /usr/opt/perl5/lib/site_perl/5.8.0/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.0 /usr/opt/perl5/lib/site_perl .
      I expected to see x=10 after the use FindBin had run down the @INC path. What do I miss ?

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
        You added a string to the list. The string happened to contain Perl syntax rather than a directory name.

        You have to use a ref to a sub, not a string to be evaled.

        sub x { print "I'm here! [@_]\n" }; use lib \&x; use FindBin; print "done.\n";
        —John

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://100475]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-03-28 23:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found