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

I'm building a web application using perl, apache2 and mod_perl2. I'm experiencing some weird stuff. When I run the app from the console, it works fine. Also using perl cgi instead of mod_perl it works fine.

When I use mod_perl I get a not found error, on the first "use"d module. All the modules are in the same dir as the .pl script, /www/domain/cgi-bin/.

When I insert "use lib '/www/domain/cgi-bin';" in the script, the app works fine. But I rather not have hardcoded paths in my script, that's what config files are for.

I tried to overcome this issue by using FindBin and FindBin::Real, and using the $0 var. But without success. The bizarre thing is that the following works:

use lib "/www/domain/cgi-bin";

but the following does NOT work:

my $path = "/www/domain/cgi-bin";
use lib $path;

and that freaks me out.

Could anyone shed some light on this please?

  • Comment on Strange issues with mod_perl and use lib

Replies are listed 'Best First'.
Re: Strange issues with mod_perl and use lib
by Joost (Canon) on May 12, 2007 at 22:49 UTC

      That doesn't fix the problem. The assignment is done earlier than it would have without the BEGIN, but it still happens after the use statement is executed.

      While the BEGIN block is executed as soon as it finishes compiling, the same goes for the use statement. Since the use statement is fully compiled before the BEGIN block is fully compiled (i.e. it ends first), the use statement is executed before the BEGIN block is executed, and therefore before the assignment is executed.

      Solutions:

      my $path; BEGIN { # Code that determines the path and stores it in $path. $path = "/www/domain/cgi-bin"; } use lib $path;

      or

      use lib do { # Code that determines the path and returns it. "/www/domain/cgi-bin" };

      or

      sub get_lib_path { # Code that determines the path and returns it. return "/www/domain/cgi-bin"; } use lib get_lib_path();

      or

      # Hardcoded use lib "/www/domain/cgi-bin";

      Update: Clarified the wording.

      Unfortunately, that doesn't work either...
Re: Strange issues with mod_perl and use lib
by perrin (Chancellor) on May 13, 2007 at 02:58 UTC
      Thank you for this excellent advice. PerlRunPrefork was indeed the solution. It works now, without hard coded directories in my code! :)
Re: Strange issues with mod_perl and use lib
by RL (Monk) on May 13, 2007 at 06:09 UTC

    That's because @INC is reset to the contents valid on Apache startup on each run. The use..bla statement is only executed the first time the script is run. On subsequent runs of the same script in the same Apache process (or it's children) the use statements are not executed again.
    At least this is my understanding from what I read.

    What I did was adding the following line to the end of
    /etc/apache2/apache2.conf:

    PerlRequire "/etc/apache2/modperl_startup.pl"

    The file modperl_startup.pl reads:

    #!/usr/bin/perl use lib "/htdocs/perl5lib"; 1;

    Hope this helps
    RL

Re: Strange issues with mod_perl and use lib
by Errto (Vicar) on May 13, 2007 at 05:28 UTC
    that's what config files are for.
    Then go ahead and put it in the config file:
    PerlSwitches -I/www/domain/cgi
    The above cribbed from the mod_perl 2.0 docs
Re: Strange issues with mod_perl and use lib
by Bro. Doug (Monk) on May 14, 2007 at 02:20 UTC
    Farenji,

    I have a large perl app with several years worth of a few dozen coder's work in it. I often see this in the code:
    my $package = "Some::Package" ; eval "require $package" ;

    It drives me ape when I see this. They forgot a key part. It should look like this:
    my $package = "Some::Package" ; eval "require $package" ; warn $@ if $@ ;
    The point is: this will work for you to include your libs at runtime.

    Peace, monks.
    Bro. Doug :wq