Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

use lib in cgi env

by AlexTape (Monk)
on Nov 05, 2012 at 13:40 UTC ( #1002326=perlquestion: print w/replies, xml ) Need Help??

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

Omniscient Monks,

i try to "use lib" in a cgi environment.


# test environment

# productive environment

Server Root = /home/user/anotherPage/

use lib "modules"; use upload; print $upload::variable;
use lib (randomly?) looks in the wrong directory

i tried FindBin, but itīs completely weird.

he gets the out of the relative /modules (/home/user/test-workspace/trunk/modules/
but the other modules are loaded from here:/home/user/webpage/modules/
- i dont understand that..

i see that there are actually three locations
print $_ . " => " . $INC{$_} . "<br>" for keys %INC; => modules/ => /home/user/webpage/modules/ => /home/user/test-workspace/trunk/module/

but all of them should be located in

kindly.. perlig.
$perlig =~ s/pec/cep/g if 'errors expected';

Replies are listed 'Best First'.
Re: use lib in cgi env
by talexb (Chancellor) on Nov 05, 2012 at 14:57 UTC

    Some meta-suggestions:

    • Wrap your code in code tags to help make it stand out.
    • If something's 'completely weird', tell us what's weird about it -- what you expected, what actually happened, and how that disagrees with the documentation.

    I suspect you didn't read what use lib actually does, otherwise you'd have a better idea what it was doing. It adds a directory path to @INC to provide Perl with additional locations for modules.

    I expect you want

    use lib '/home/user/test-workspace/trunk/modules';
    for development and
    use lib '/home/user/webpage/modules/';
    for production.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      the weird thing is that i am not able to use a relative lib because he is mixing the pathes.. is there any kind of priority or something like this in which order perl looks for the modules in the known folder (@INC)?
      $perlig =~ s/pec/cep/g if 'errors expected';

        Yes - see perlvar for @INC, which links to require, which shows the (pseudo-)code that require uses. It looks through @INC in order of entry appearance.

Re: use lib in cgi env
by sundialsvc4 (Abbot) on Nov 05, 2012 at 15:08 UTC

    In a recent (FastCGI) application main-script, I once did this:

    BEGIN { if (-f '/opt/location1/') { ## production environment: unshift( @INC, '/opt/location1/lib', '/opt/location1/scripts' ); } else { ## dev environment: unshift( @INC, '/opt/location2/lib', '/opt/location2/scripts', '/opt/location3/debug_lib' ); } }

    The BEGIN block’s contents are executed before compilation begins, and therefore can be used to determine things such as library locations.   This example used the existence of a particular file in a particular location to decide where the libraries would be.   The use lib nomenclature was not used.

    Developers relied upon setting the PERL5LIB environment variable to establish the library-location (appropriate to their particular machines), as the above mechanism would not have been invoked as they wrote and tested their code.

    I’m not saying that this is the only way nor necessarily the best one.   But, it did work.

Re: use lib in cgi env
by 2teez (Vicar) on Nov 05, 2012 at 14:51 UTC

    You want to get at the your .pm files in /home/user/test-workspace/trunk/modules/?
    If I get your question right, then why not do:

    use lib "test-workspace/trunk/modules"; use upload; print $upload::variable;
    But also know that $variable must also be a global variable,declared either using our $variable; or use vars qw($variable);
    Hope this help

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      because i assumed to have a relative path. the absolute method is working well..
      $perlig =~ s/pec/cep/g if 'errors expected';
Re: use lib in cgi env
by kcott (Archbishop) on Nov 05, 2012 at 21:03 UTC

    G'day perlig,

    Your main problem seems to be that the directory structures of your test and production environments do not mirror each other. The relative path for your test environment would be:

    use lib './modules';

    but, for your production environment, you'd need

    use lib '../modules';

    While you may need different settings (such as in a configuration file), you shouldn't be changing code between development and testing environments nor between testing and production environments. If you do make code changes, then you're neither testing what you developed not delivering what was tested.

    Furthermore, the scenario you describe suggests that you are going to have to make code changes in the production environment. This is something you should strenuously avoid if you wish to maintain a stable production environment.

    I would expect you to encounter related problems for the life of the application while your environments remain out of sync.

    I don't have enough information to provide a definitive answer on how to fix this. Here's a few potential options (that allow use lib './modules'; to work everywhere):

    • Move /home/user/webpage/trunk/ to /home/user/webpage/
    • Move /home/user/webpage/modules/ to /home/user/webpage/trunk/modules/
    • Create a symlink called /home/user/webpage/trunk/modules/ which points to /home/user/webpage/modules/

    However you decide to fix this, make sure it applies to all environments: I mentioned development in addition to test and production - you may have others.

    -- Ken

      The development environment looks as though its an SVN (Subversion) checkout, hence the inclusion of the trunk in the path. If so, the originator does get top marks for version controlling his code. Having said that, he should probably have just checked out a copy of the trunk to a local sandbox and avoided having "trunk" in the path.

      svn co http://your_repository/trunk local_directory is a good way to avoid this. This would have solved the discrepancy between his "development" and "production" relative paths and avoided the problem described. I still stick to my earlier statement that setting PERL5LIB or similar environment variable is the best way to resolve the problem. I presume the production version runs as a different user from the development version, so this could be accomplished by setting the environment variable in ~/.bashrc or the Apache config files.

      I'll leave exactly how to do that as a Google exercise as its getting past my bedtime :-)

      itīs a little bit complicated.. but the "productive env" is in that case a "productive test env" ;-) whatever.. i mind of these things you say.. thank you!
      $perlig =~ s/pec/cep/g if 'errors expected';
Re: use lib in cgi env
by space_monk (Chaplain) on Nov 05, 2012 at 16:37 UTC
    Embedding a fixed path in the code is not a good plan. Why not try alternative methods of setting a path for libraries, such as setting the PERL5LIB environment variable, or starting perl with the include path on the command line?

      The problem here is how (and whether) that environment-variable will be set when the CGI/FastCGI script executes.   The web-server e.g. Apache sets up a more limited environment so that the runtime behavior of the script is more certain and less subject to undue influence.

      In the specific case of a CGI script destined for a known implementation target, I find that setting fixed paths is a reasonable and perhaps desirable technique.   You know what the right answers are and always will be.   And, as noted above, I isolate it into one root script which is known to have global influence upon the rest of it.   Your Mileage May Vary™, but in the specific case I described above, what I chose to do was a most-deliberate choice that did fully consider what you suggest.

Re: use lib in cgi env
by fullermd (Priest) on Nov 06, 2012 at 00:15 UTC

    I have a common little snippet I drop at the top of a lot of projects, to set use lookup paths relative to the running binary.

    my $rundir; BEGIN { use File::Basename; $rundir = dirname($0); } use lib "$rundir/lib";

    Then you can have

    /any/old/random/place/ /any/old/random/place/lib/

    and just use Foo, relocating the whole project at will. Obviously not perfect against the case of you running the script via alternate hardlinks or such, but...

      thank you! thats what i looked for..
      $perlig =~ s/pec/cep/g if 'errors expected';
Re: use lib in cgi env
by remiah (Hermit) on Nov 05, 2012 at 22:38 UTC


    FindBin works good to me. And it seems suit for your need well...

    It unshift paths to @INC properly for me, and I wonder what is the result of @INC in your case. This will show the result of @INC after use libed.

    #!/usr/bin/perl use FindBin qw($Bin); use lib ($Bin,"$Bin/../../mycpan"); print "Content-type: text/html; charset=UTF-8\n\n"; print "$_<br>\n" for @INC;
    Here unshift @INC, current directory and relative mycpan directory.

    FindBin do good to me.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1002326]
Approved by marto
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (1)
As of 2022-11-26 18:44 GMT
Find Nodes?
    Voting Booth?