Does the otherlibdirs Configure option rewrite or just modify #INC? - perl

I'm a perl noob and I have a very basic question regarding the #INC post: How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
Does the "otherlibdirs" Configure option completely rewrite the directories that are part of #INC, or merely add another directory? It's not clear to me from that answer what it does, and I don't want to screw up the whole #INC path.
Thanks!

Perusing source of the Perl Configure script, we find the following usage information:
case "$otherlibdirs" in
''|' ') dflt='none' ;;
*) dflt="$otherlibdirs" ;;
esac
$cat <<EOM
Enter a colon-separated set of extra paths to include in perl's #INC
search path, or enter 'none' for no extra paths.
EOM
So if you compile Perl with something like
Configure -Dotherlibdirs=/usr/foo/bar:/usr/foo/bar/baz
Then the directories /usr/foo/bar and /usr/foo/bar/baz will be appended to the normal #INC built-in to the perl binary.

Related

My Perl code does not seem to work with .lib?

I'm new to both Perl and its feature of .lib.
I made this simple subroutine and saved it as a file with an extension of .lib
sub shorterline {
print "Content-type: text/html\n\n";
}
1;
As I tried to insert the subroutine into the Perl file with an extension of .cgi below, it doesn't work somehow:
#!/usr/bin/perl
require 'mysubs.lib';
&shorterline;
print "Hello, world!";
I gave the .cgi the chmod permission, but the .cgi still doesn't work, what seem to be the problem ?
Your descriptions of what the problem is are rather unclear.
it doesn't work somehow
the .cgi still doesn't work
Without knowing what problems you're seeing, it's hard to know what the problem is. But I tried copying your code and running the program from the command line and I got this error message:
Can't locate mysubs.lib in #INC (#INC contains: ...)
So I think you are using a recent version of Perl and are running up against this change:
Removal of the current directory (".") from #INC
The perl binary includes a default set of paths in #INC. Historically it has also included the current directory (".") as the final entry, unless run with taint mode enabled (perl -T). While convenient, this has security implications: for example, where a script attempts to load an optional module when its current directory is untrusted (such as /tmp), it could load and execute code from under that directory.
Starting with v5.26, "." is always removed by default, not just under tainting. This has major implications for installing modules and executing scripts.
If this is the problem, then you can fix it by adding the script's directory to #INC as follows:
use FindBin qw( $RealBin );
use lib $RealBin;
before your call to require. If that doesn't solve your problem, perhaps you would consider sharing a little more detail about the problems that you are experiencing.

What does perl -I means

I see this a lot in bash scripts and I cannot see this in the manual and other sites.
What does the -I in running a perl script mean?
It is run like this:
perl -I$prod_dir $prod_dir/script.pl <parameter1> <parameter2>
Can someone explain it to me?
-Idirectory
Directories specified by -I are prepended to the search path for modules (#INC ).
Source: perlrun documentation
It means perl will include the modules available under specified directory following -I which is $prod_dir in your case.
By default Perl picks up modules from #INC. If you want to use a module which is not available in #INC then you can specify the directory using -I. This specified directory will be appended to #INC at run time.
Also read:
How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
How to change #INC to find Perl modules in non-standard locations

Using a Perl module in my own directory [duplicate]

I have a module in the parent directory of my script and I would like to 'use' it.
If I do
use '../Foo.pm';
I get syntax errors.
I tried to do:
push #INC, '..';
use EPMS;
and .. apparently doesn't show up in #INC
I'm going crazy! What's wrong here?
use takes place at compile-time, so this would work:
BEGIN {push #INC, '..'}
use EPMS;
But the better solution is to use lib, which is a nicer way of writing the above:
use lib '..';
use EPMS;
In case you are running from a different directory, though, the use of FindBin is recommended:
use FindBin; # locate this script
use lib "$FindBin::RealBin/.."; # use the parent directory
use EPMS;
There are several ways you can modify #INC.
set PERL5LIB, as documented in perlrun
use the -I switch on the command line, also documented in perlrun. You can also apply this automatically with PERL5OPT, but just use PERL5LIB if you are going to do that.
use lib inside your program, although this is fragile since another person on a different machine might have it in a different directory.
Manually modify #INC, making sure you do that at compile time if you want to pull in a module with use. That's too much work though.
require the filename directly. While this is possible, it doesn't allow that filename to load files in the same directory. This would definitely raise eyebrows in a code review.
Personally I prefer to keep my modules (those that I write for myself or for systems I can control) in a certain directory, and also to place them in a subdirectory. As in:
/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm
And then where I use them:
use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;
As an aside.. when it comes to pushing, I prefer the fat-arrow comma:
push #array => $pushee;
But that's just a matter of preference.
'use lib' is the answer, as #ephemient mentioned earlier. One other option is to use require/import instead of use. It means the module wouldn't be loaded at compile time, but instead in runtime.
That will allow you to modify #INC as you tried there, or you could pass require a path to the file instead of the module name. From 'perldoc -f require':
If EXPR is a bareword, the require assumes a ".pm" extension and
replaces "::" with "/" in the filename for you, to make it easy to
load standard modules. This form of loading of modules does not risk
altering your namespace.
You have to have the push processed before the use is -- and use is processed early. So, you'll need a BEGIN { push #INC, ".."; } to have a chance, I believe.
As reported by "perldoc -f use":
It is exactly equivalent to
BEGIN { require Module; import Module LIST; }
except that Module must be a bareword.
Putting that another way, "use" is equivalent to:
running at compile time,
converting the package name to a file name,
require-ing that file name, and
import-ing that package.
So, instead of calling use, you can call require and import inside a BEGIN block:
BEGIN {
require '../EPMS.pm';
EPMS->import();
}
And of course, if your module don't actually do any symbol exporting or other initialization when you call import, you can leave that line out:
BEGIN {
require '../EPMS.pm';
}
Some IDEs don't work correctly with 'use lib', the favored answer. I found 'use lib::relative' works with my IDE, JetBrains' WebStorm.
see POD for lib::relative
The reason it's not working is because what you're adding to #INC is relative to the current working directory in the command line rather than the script's directory.
For example, if you're currently in:
a/b/
And the script you're running has this URL:
a/b/modules/tests/test1.pl
BEGIN {
unshift(#INC, "..");
}
The above will mean that .. results in directory a/ rather than a/b/modules.
Either you must change .. to ./modules in your code or do a cd modules/tests in the command line before running the script again.

Can't locate Connection.pm in #INC (#INC contains: /usr/local/lib/perl/5.14.2 /etc/perl /usr/local/share/perl/5.14.2 ....) at ./select.cgi at line

I am trying my hands for the first time in -> Apache - Perl (CGI) on Ubuntu.
The Apache server is working fine in the folder /var/www for the default index.html file. But since I want to run a CGI script, I also installed (just in case) DBI, as suggested by some forums. I set the permissions for complete access to my cgi-bin folder in which the select.cgi script resides. I tried tweaking the select.cgi script multiple times redirecting the library to the Perl library, but to no avail. I modified the httpd.conf file and set the directory path to the select.cgi folder. That didn't work. I also defined ScriptAlias, and set it to the working directory. That didn't work either.
Does anyone have any helpful pointers. Thanks.
This is not exact solution that you want but the overall idea is like below.
How to resolve Cant locate xxxx.pm in #INC path problem
By default perl looks for modules in the standard library path and the current directory.
Sometimes you need to use some modules that are installed in non standard locations; there are several ways to deal with this situation:
To check whether your module is in #INC path use.
Example:
perl -e 'use SOAP::Lite;'
perl -e 'use Error;'
If you run these commands on a system that has SOAP::Lite and Error installed, Perl will simply return from these commands without printing any output.
To check current standard library path use:
perl -le 'print foreach #INC'
If you have the administrative privileges, then best solution is to install the module in any of the system defined library path.
Set the environment variable PERL5LIB
Perl will look for modules in the directories specified in PERL5LIB environment variable before looking in the standard library and current directory.
So you can set this variable to locate your modules.
Example:
# For unix like systems
PERL5LIB=/home/path/lib:/usr/another/path/lib; export PERL5LIB
Note: separate the directories with colons on unix and with a semicolon on Windows.
IF you are running your code from command line then use -I parameter. The syntax should be something like.
perl -I /home/path/lib -I /usr/another/lib script.pl
And you can also Add the library path in your script
The command for including the path in your script is: use lib path.
Example:
#!/usr/bin/perl
use lib "/home/path/lib";
use lib "/usr/another/lib";
use MyCustomModule;
In a comment, you gave information that contradicts what you gave originally. The latter information appears to be more reliable, so I'll use it.
I believe you said the path to the module is
/usr/lib/perl5/vendor_perl/5.8.5/foo/bar/Connection.pm
and that the error message you got (with line breaks added) is:
Can't locate foo/bar/Connection.pm in #INC (#INC contains:
/etc/perl
/usr/local/lib/perl/5.14.2
/usr/local/share/perl/5.14.2
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.14
/usr/share/perl/5.14
/usr/local/lib/site_perl
.
/usr/lib/perl5/vendor_perl/5.8.5/foo/bar/
) at ...
You did something like
use foo::bar::Connection;
or
require "foo/bar/Connection.pm";
Perl looked for
/etc/perl/foo/bar/Connection.pm
/usr/local/lib/perl/5.14.2/foo/bar/Connection.pm
...
/usr/lib/perl5/vendor_perl/5.8.5/foo/bar/foo/bar/Connection.pm
But none of those are
/usr/lib/perl5/vendor_perl/5.8.5/foo/bar/Connection.pm
It's simple to fix. Add the following to your script:
use lib '/usr/lib/perl5/vendor_perl/5.8.5';
The other possible fix is to use
use Connection;
instead of
use foo::bar::Connection;
Which fix is the correct fix depends on what that package line in side the module looks like. If you find package foo::bar::Connection;, you need to modify #INC (as shown with use lib, for example). If you findpackage Connection;, you need to change theuse` directive.

gvim can't locate the Perl modules

I'm trying to write a function in gvim that would use the module File::Path.But
it alert me "Can't locate File/Path.pm in #INC(#INC contains: .) at (eval 8) line 1.
BEGIN failed--compilation aborted at (eval 8) line 1." when gvim start.
I know it means gvim couldn't find my perl lib path.
So,my question was :
How to tell gvim the correct path to locate the Perl modules?I have tried to add use lib'C:/Perl/lib'; but the problem continued.
Thank you~~~
if has("perl")
function! Make_dir()
perl make_dir();
endfunction
autocmd VimEnter * call Make_dir()
perl <<EOF
use File::Path;
sub make_dir{
my $bakup=$ENV{'HOME'}."/bakup" ;
mkdir $bakup if not -e _;
#VIM::SetOption("backup");
#VIM::SetOption("backupdir=$bakup");
#VIM::Msg($bakup);
#todo....
}
EOF
endif
Did you "censor" your output, or does it really say just "(#INC contains: .)"? That would seem to indicate a bad installation of Perl. It should have a few more directories in there. It could indicate a permission problem, I imagine.
use lib doesn't work because Perl can't find lib.pm or any other module it comes with. -I should work though, but it would only be a bandaid fix.
http://vim.wikia.com/wiki/Script:556
BTW,I tried the way on vim tips wiki also...but the problem continued