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

I have a CGI application that needs to work cross platform. It is running well on *nix. On windows I am having trouble with the program either executing a do statement or ???
do "./common.inc"; my $input = new CGI(); my $config = getConfig($input->param('extracfg'));
getConfig is a defined subroutine that exists in common.inc along with several other routines and assigning some common values for the application, but the browser is giving me: Undefined subroutine &main::getConfig called at ..... The logfiles IIS generates are useless in helping me sort out what is happening. I have tried giving the full path to common.inc, just common.inc and as you see it in the code. Permissions seem to be that the web_user has full access to the file (just trying to get it to work).

I am sure I am overlooking something, but Windows has given me snake bites in the past.

g_White

Replies are listed 'Best First'.
Re: Do not working as expected on Windows
by ikegami (Patriarch) on Sep 04, 2007 at 15:16 UTC

    You didn't check if do succeeded.

    if (!do($include)) { my $error = $@ ? $@ : $! ? $! : 'did not return a true value'; die("Unable to load common stuff: $error\n"); }

    It probably failed because the current working directory is not what you think it is.

    Use absolute paths,

    use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); my $include_fq = rel2abs('common.inc', dirname(rel2abs($0))); if (!do($include_fq)) { my $error = $@ ? $@ : $! ? $! : 'did not return a true value'; die("Unable to load common stuff: $error\n"); }

    use absolute paths in @INC,

    use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); use lib dirname(rel2abs($0)); if (!do('common.inc')) { my $error = $@ ? $@ : $! ? $! : 'did not return a true value'; die("Unable to load common stuff: $error\n"); }

    or change the current directory to where you expect it to be.

    use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); BEGIN { chdir(dirname(rel2abs($0))); } if (!do('common.inc')) { my $extra = $@ ? ": $@" : $! ? ": $!" : ': did not return a true value'; die("Unable to load common stuff$extra\n"); }

    P.S. — What's with "./"? "./foo" is the same thing as just "foo".

    Update: Added $!/$@ to the error message when do sets them.
    Update: Added use lib solution.

      Using the code that works with the @INC looks like the best option for me, one question on it, I have already set some libraries to use for some special reporting code, will the use lib statement in your snippet have any negative effect?

      g_White

        @INC is the search path used by do, require and use. use lib adds a path to the front of @INC. That could only lead to a problem if you have two identically named modules in different paths. Then, do/require/use might load the wrong one.