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

This is a simple question for all you perl geniuses. I'm trying to require code in a separate directory off my main directory. I have tried so many different variations to get this to work. I've even tried to push '.\\modules' onto the @INC array before calling require. Nothing works. Can someone help?
$dir = 'modules'; $mod = 'test'; $pkg = sprintf("%s::%s",$dir,$mod); require $pkg; print test::func(), "\n";
#code in modules\test.pm package test; sub func() { print "hello from test\n"; } 1;
thanks, Michael

Replies are listed 'Best First'.
Re: requiring perl modules
by chromatic (Archbishop) on Dec 03, 2003 at 17:59 UTC

    According to require, if the argument to require is not a bareword (if it's a variable as you have or an expression returning a name), Perl doesn't automatically add the .pm extension. I suspect you could get by with something like this:

    use File::Spec; my $dir = 'modules'; my $mod = 'test'; my $module = File::Spec->catfile( $dir, $mod . '.pm' ); require $module;

    The documentation also suggests this, which I don't like, though it is shorter:

    eval "require $mod";
      It was my recollection that require expected (or at least allows) a posix-style pathname, e.g. require "$dir/$mod.pm". Could someone on VMS or a Mac try with catfile, with '/', and via eval "require $mod" and report which work (as well as what they put in %INC)? I would find it very helpful to know for sure.
Re: requiring perl modules
by hardburn (Abbot) on Dec 03, 2003 at 18:02 UTC

    As covered in the require documentation, when require gets a string (instead of a bare statement), it doesn't automatically translate the '::' for you. You'll need to change your code to one of the following:

    # Change the sprintf . . . $pkg = sprintf("%s/%s", $dir, $mod); # . . . OR change the require to be inside an eval eval "require $pkg";

    In the second form, the expanded variable looks like a bare statement to require, so the '::' translation works.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: requiring perl modules
by Zed_Lopez (Chaplain) on Dec 03, 2003 at 19:17 UTC

    Just enter perl -V to examine your @INC list. It probably includes '.', i.e. the current directory, in which case, like the Anonymous Monk above, require modules::test will work.

    Or you can use lib '.\modules' (equivalent to unshifting @INC, only in a BEGIN block) and then require test.

    Or, unless there's some reason you need to defer loading the module, just:

    use lib '.\modules'; use test;
Re: requiring perl modules
by Anonymous Monk on Dec 03, 2003 at 18:57 UTC
    try require modules::test; It works for me.