http://www.perlmonks.org?node_id=285370

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

Hello all!

My project is placed in two different locations depends whether I'm on the development environment or on the production environment, therefore I have an enviraonment variable that holds the location according to the environment. The problem is that I need to do:
use lib $projectLocation; # the environment variable I was talking +about
and this doesn't seem to work, I shouts a lot of error regarding uninitialized values in lib.pm. It seems that this work only when writing the path explicitly, like that:
use lib '/some/location/';
Is there something I can do?

Hotshot

Replies are listed 'Best First'.
Re: Problems with 'use lib'
by lestrrat (Deacon) on Aug 21, 2003 at 06:41 UTC

    Remember that "use" statement is executed at compile time. Most likely your $projectLocation is not initialized. You could do something like this instead:

    BEGIN { my $projectLocation = '...'; # somehow initialize this unshift @INC, $projectLocation; } use MyProjectPackage;
Re: Problems with 'use lib'
by esh (Pilgrim) on Aug 21, 2003 at 07:41 UTC

    The thing is I'm initializing $projectLocation to the invironment variable if it exists, otherwise I initialize (in my development environment), on the production environment it doesn't exist so initialize it to another location (predifined one).
    Putting it all together I offer:
    my $projectLocation; BEGIN { $projectLocation = $ENV{DEVLOCATION} || '/default/production/location'; } use lib $projectLocation;

    -- Eric Hammond

      You can do that all in one line, no BEGIN block needed:
      use lib $ENV {DEVLOCATION} || '/default/production/location';

      Abigail

Re: Problems with 'use lib'
by shenme (Priest) on Aug 21, 2003 at 06:53 UTC
    When and where does $projectLocation get defined?

    The "use lib" action is done at compile time, before statements like

    my $projectLocation = '/some/other/place';
    can be executed to set the variable.   You need to force your value to be defined during compilation.   Perhaps this might be more like what you were thinking?
    BEGIN { my $projectLocation = '/some/other/place'; use lib $projectLocation; }
    But then this gets back to something like the starting question - where does the value for $projectLocation come from?   Ah, an environment variable.   So maybe
    BEGIN { use lib $ENV{MYLIBRARYDIR}; printf "in BEGIN: '%s'\n", join("', '", @INC ); }
    will do what you want.

      I don't think this code will do what you want:

      BEGIN { my $projectLocation = '/some/other/place'; use lib $projectLocation; }
      The "use lib" inside the BEGIN block will be executed before the assignment since it is also inside the BEGIN block. Try this instead:
      my $projectLocation; BEGIN { $projectLocation = '/some/other/place'; } use lib $projectLocation;
      The "use" is like another BEGIN so these two pieces of code will be executed in sequence now.

      -- Eric Hammond

        I was going to say that wasn't true, but went back and looked at the last test program I was using and decided I hadn't tested that situation correctly.   Using code
        BEGIN { my $foo = 'foom'; use lib $foo; }
        results in error messages
        Use of uninitialized value in string eq at /usr/lib/perl5/5.8.0/i386-linux-thread-multi/lib.pm line 29.
        Empty compile time value given to use lib at hotshot.pl line 5
        
        Using your code
        my $foo; BEGIN { $foo = 'foom'; } use lib $foo; printf "executing: '%s'\n", join("', '", @INC );
        returns the desired results
        executing:  'foom', '/usr/lib/perl5/5.8.0/i386-linux-thread-multi', ... , '.'
        
        Just to try something different I tried
        BEGIN { our $foo = 'foom'; } use lib $foo;
        which also worked.

        Another thing to put in the list of things to re-study.   Key is that "use" (and other pragmas?) are executed (at compile time) before surrounding code at the same apparent 'level'.   By enclosing code in a BEGIN block ahead of the "use" we force it into compile time execution before the following "use" is executed.   (Or something like that ;-)

Re: Problems with 'use lib'
by The Mad Hatter (Priest) on Aug 21, 2003 at 12:04 UTC
    Instead of using use lib and fiddling with environment variables, is there a reason you can't just set the environment variable PERL5LIB to whatever value is necessary?
Re: Problems with 'use lib'
by tcf22 (Priest) on Aug 21, 2003 at 06:53 UTC
    You say that it is an environment variable. Do you assign the variable to $projectLocation before you use lib. Try printing out $projectLocation before it is used, to see what its value is. Perhaps this will work:
    use lib $ENV{projectLocation}; #or whatever the env variable is
Re: Problems with 'use lib'
by TomDLux (Vicar) on Aug 21, 2003 at 19:42 UTC

    The best solution is to use environment variables to modify the included path during development, or you could use perl -I ...

    If you're up-to-date with your Perl binary, there's also conditional modules:use if <cond>, MODULE qw/.../

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

Re: Problems with 'use lib'
by hotshot (Prior) on Aug 21, 2003 at 07:19 UTC
    The thing is I'm initializing $projectLocation to the invironment variable if it exists, otherwise I initialize (in my development environment), on the production environment it doesn't exist so initialize it to another location (predifined one).

    Hotshot