Reputation: 2501
Let's imagine we are new to perl and wrote some great module MyModule.pm
. We also wrote some great script myscript.pl
, that need to use this module.
use strict;
use warnings;
use MyModule;
etc...
Now we will create dir /home/user/GreatScript
and put our files in it. And trying to run myscript.pl
...
cd /home/user/GreatScript
perl myscript.pl
Great! Now moving to another dir...
cd /
perl /home/user/GreatScript/myscript.pl
Getting some not very usefull error about @INC
and list of paths. What is this? Now after some googling we know that @INC
contains paths where to search our modules, and this error means that Perl can't find out MyModule.pm.
Now we can:
@INC
Install our module to one of dirs from @INC
@INC
in the BEGIN
section
Add use lib '/home/user/GreatScript';
to our script, but it looks bad. What if we will move our script to other dir?FindBin
module to find our current dir, and use this path in use lib "$FindBin::Bin";
, but it's not 100% effective, for example some bugs with mod_perl or issues...abs_path
method from Cwd
module. Looks like a yet another bicycle?Why this obvious and regular operation need a lot of work? If I have one script, it's easy... But why I need to write this few additional lines of code to all my scripts? And it will not work 100%! Why perl not adding current script dir to @INC
by default, like it does with "."?
PS: I was searching for answer to my question but find only list of solutions from the list above and some others. I hope this question is duplicate...
Upvotes: 4
Views: 1086
Reputation: 3272
That is need in order to know which module would you like to use. When you move to another catalog as you said perl looks in '.' catalog so if run:
cd /
perl /home/user/GreatScript/myscript.pl
and if MyModule.pm in '/' perl will find it and will be use in myscrpit.pl
. Now as Perl finds module in the @INC in order which catologs in it you have to keep an eye on @INC.
Summary: obvious and regular operation is need to prevent using wrong module with the same name what you want to use.
Upvotes: 2
Reputation: 4581
If your use case is: "I want to have a script which accesses additional modules or other resources in the same or relative directory, and I don't want to install everything", then FindBin is a perfect solution. The limitation mentioned in the manpage happens only in persistent environments like mod_perl, but here I would propose different solutions (e.g. using FindBin only within httpd.conf, not in the scripts/modules).
(/me is a heavy FindBin user, and I am also the author of half of the KNOWN ISSUES section of the FindBin manpage)
Upvotes: 4
Reputation: 27197
Or some forgotten or missing ( Did I miss something? )
Another option: Don't keep your module with your script. The module is separate because it is re-usable, so put it in a library folder. This can be anything from a local library for personal projects, included with use lib
(and perhaps referencing an environment variable you have set up for the project), to making the module into a CPAN library, and letting cpan
manage where it goes. What you decide to do depends on how re-usable your code is, beyond how the script uses it.
Why this obvious and regular operation need a lot of work?
It is not a lot of work in the scheme of things. Your expectation that files grouped together in the file system, should automatically be used by Perl at the language level to resolve require
or use
statements is not true. It's not that it is impossible, or that your expectation is unreasonable, just that Perl is not implemented that way. Changing it after the fact could affect how many existing projects work, and may be contentious - so is unlikely to change.
Upvotes: 5