Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

using "require" problem

by gauss76 (Scribe)
on Sep 26, 2017 at 07:51 UTC ( [id://1200087]=perlquestion: print w/replies, xml ) Need Help??

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

Hi All

I have the following problem and don't know how to resolve it.

Basically, I have a perl .pl file (main.pl) that requires another .pl file (routines.pl) in order to work correctly (everything running on a Linux machine). The files are both in the same folder and I currently use the following syntax in the file main.pl

require "./routines.pl";

This works fine if I run main.pl from the folder that contians the two files. However if I run the program from a different folder with, say, the command

perl /home/user/code/main.pl

Then I get an error saying "can't locate ./routines.pl.

I know that I can change the "require" statement to:

require "/home/user/code/routines.pl"

However, for me, this is not an option as I need to copy the code to another Linux system where the containing folder will be different (the two files will still be in the same folder)

So, my question: Is there any way to use the same "require" statement so that I can run my program from any folder with the command

perl /home/user/code/main.pl

where the folder for the code (/home/user/code/main.pl) can change?

Please let me know if anything is not clear.

Many thanks for any help on this

gauss76

Replies are listed 'Best First'.
Re: using "require" problem
by haukex (Archbishop) on Sep 26, 2017 at 07:54 UTC

    For paths that are always relative to the script's location, the core module FindBin works well:

    use FindBin; require "$FindBin::Bin/routines.pl";

    Update: hippo makes a good point that require will search @INC, so yet another way to make it work is with lib, as I showed here, and below. But I also agree with Discipulus' point that turning the file into a separate package might be a good idea too.

    use FindBin; use lib $FindBin::Bin; require "routines.pl";
Re: using "require" problem
by Discipulus (Canon) on Sep 26, 2017 at 07:58 UTC
    Hello gauss76,

    Normally you will put your routines into a module: Routines.pm will be the name of the file with inside a package called Routines You can use Exporter to export, possibly just on demand, one or more subs.

    Consider also that current directory . is no more included in @INC in newer Perl version for security reasons: you can include it with use lib '.'; (or adding it directly to @INC or using the -I perl switch) PS this is probably unrelated (see below) but important to know anyway

    Look at my homenode for many links about modules and code reuse: especially require "shared.pl" with use strict; and Include subs from different perl file

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Consider also that current directory . is no more included in @INC in newer Perl version for security reasons: you can include it with use lib '.'

      While correct, the way I understood the question is that the working directory is changing, so I don't think that would help here - but this pattern would, which I've used many times:

      use FindBin; use lib $FindBin::Bin; use Routines;
Re: using "require" problem
by hippo (Bishop) on Sep 26, 2017 at 08:01 UTC
    $ mkdir -p /tmp/foo/bar $ echo 'require "routines.pl";' > /tmp/foo/bar/main.pl $ echo 'print "foo!\n";' > /tmp/foo/bar/routines.pl $ export PERL5LIB=/tmp/foo/bar $ perl /tmp/foo/bar/main.pl foo! $

    See also the reference to @INC in perlvar.

Re: using "require" problem
by Anonymous Monk on Sep 26, 2017 at 13:07 UTC
      UNIVERSAL::require

      As I already said here: That module has a huge caveat and I wouldn't recommend it. It adds two methods to the UNIVERSAL class, the base class for all Perl classes. This means that loading this module can affect every single class and object in the program.

      I'm also not sure how it applies to the OP's question, I see nothing in its documentation regarding @INC, instead it "works exactly like Perl's require".

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (2)
As of 2024-04-24 17:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found