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

Esteemed Monks,

I have a script foo.pl and a module Bar.pm both located together in a directory /my/stuff . In foo.pl I have:

use Bar; ...etc
If my present working directory is /my/stuff and I run foo.pl everything is great. If my pwd is /somewhere/else and I execute /my/stuff/foo.pl I fail like so this:
Can't locate Bar.pm in @INC (@INC contains: /usr/local/lib/perl5/5.005 +03/sun4-solaris /usr/local/lib/perl5/5.00503 /usr/local/lib/perl5/sit +e_perl/5.005/sun4-solaris /usr/local/lib/perl5/site_perl/5.005 .)
OK, so I could fix this by putting Bar.pm in one of the @INC dirs or by adding /my/stuff to the PERL5LIB ENV var prior to running the script. However, for several reasons, it would be much easier for me, and I would prefer to, modify foo.pl. Since the use statement is done at compile time, there is nothing I can do in the foo.pl script to keep the use Bar syntax if Bar.pm isn't already in the @INC.

I can replace  use Bar; with  require "Bar.pm"; and this seems to work.

Question: what effects does using 'require' instead of 'use' for a module have?

-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday

Replies are listed 'Best First'.
Re: Question regarding "require" or "use"
by davido (Cardinal) on Oct 02, 2003 at 17:54 UTC
    I can replace use Bar; with require "Bar.pm"; and this seems to work.
    Question: what effects does using 'require' instead of 'use' for a module have?

    To quote Camel II:

    use is exactly equivalent to the following:
    BEGIN { require Module; import Module LIST; }

    So it would seem that by using 'require' rather than 'use' you are missing out on importing from Module whatever it has to export. You also miss out on bringing the module in at compile time instead of runtime.

    UPDATE: chromatic's followup is accurate and helpful. His solutions show how to direct Perl to the path of Foo.pm. The OP's use of the name 'Foo.pm' suggests a module, but it is in fact a filename, and requires that the full path be expressed. The portion about require not taking advantage of import and the BEGIN block is still relevant, and you can see by chromatic's solutions that the issue has to be delt with one way or another.

    Dave

    "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

      While that's true, that bit of the Camel refers to require Module;, not require "FileName";. In the first case, Perl will resolve a module name to a file path. In the second case, Perl will treat the string as a file path and attempt to resolve it accordingly. (I don't have the source in front of me, so I'll wave my hands over some DWIMmery — there may be a Perl_looks_like_plain_module_name() macro in play there.

      To solve the original poster's problem, either solution one or two will work:

      # solution 1 use lib '/path/to/bar/parent/directory'; use Bar; # solution 1b use lib '/path/to/bar/parent/directory'; BEGIN { require Bar; Bar->import(); } # solution 2 BEGIN { require "/path/to/bar/parent/directory/Bar.pm"; Bar->import(); }
        Hi, Unfortunately, solution #1 won't work in my case because I want the script to determine at runtime where it is located. I don't want to hardcode a path.

        updateWhat does the BEGIN block accomplish compared to not having it enclosed like that?

        -------------------------------------
        Nothing is too wonderful to be true
        -- Michael Faraday

Re: Question regarding "require" or "use"
by TropicalD (Novice) on Oct 02, 2003 at 18:48 UTC
    Try FindBin module to find the module.

    Example:

    use FindBin; use lib $FindBin::Bin; #ensure we can find ParseUtil use ParseUtil qw(Util1 Util2 Util3 );
    Regards