I have a perl script myscript.pl and configuration file myscript.conf. Both are in same directory and I have included the conf in myscript.pl by require 'myscript.conf';
If I run myscript like ./myscript.pl , it works fine. If I run with full path like /full/path/myscript.pl it raises an error
Can't locate myscript.conf in #INC
How can I resolve this issue?
The error is not because you are using the full path when you run the program, but because the current working directory is different from the location of the script. The current directory . appears in #INC so perl will always look there for modules, but the current directory has to be correct for it to find them.
The canonical way of adding a library location that is relative to the location of the script itself is with the FindBin module, like this
use FindBin;
use lib $FindBin::Bin;
require 'myscript.conf';
Add
use lib '/full/path/'
At the begining of your program. This will add the path to #INC
Related
I'm on Windows 7, I downloaded a CPAN module called XML::XPath, and I want to use it in a script I wrote.
I cannot modify #INC on my machine, I cannot modify environmental variables on my machine, I cannot run make on my machine, and I cannot use a package manager on my machine.
So in order to use the module, I went to the CPAN website, downloaded the module's .tar.gz file, and unzipped it into a lib folder in my project. I did that because this guide suggested that I can use use lib in the context of my script to reference the downloaded module:
Adding a use lib statement to the script will add the directory to #INC for that specific script. Regardless who and in what environment runs it.
My script is called test.pl. I am trying to use the XML::XPath module to parse an XML file called test.xml. Here is an example of my directory structure:
C:/
→ sandbox/
test.pl
test.xml
→ lib/
→ XML-XPath-1.13/
XPath.pm
→ XPath/
XMLParser.pm
(etc.)
This is my test.pl script:
#!/usr/bin/perl
use strict;
use warnings;
use lib qw("C:/sandbox/lib/XML-XPath-1.13");
my $xml_file = "C:/sandbox/test.xml";
my $result;
if (-f $xml_file) {
$result = XML::XPath->new(filename => "$xml_file");
}
When I run this script with perl test.pl, the script fails with the following error:
Can't locate object method "new" via package "XML::XPath" (perhaps you forgot to load "XML::XPath"?) at test.pl line 10.
Can I resolve this error with use lib?
EDIT:
When I add use XML::XPath; to my test.pl script, as such:
#!/usr/bin/perl
use strict;
use warnings;
use lib qw("C:/sandbox/lib/XML-XPath-1.13");
I get an error like:
Can't locate XML/XPath.pm in #INC
But as stated above, I cannot physically modify #INC or recompile Perl on my machine.
This is not going to work. XML::XPath depends on the XML::Parser module which needs to be compiled. Since you do not have a complete toolchain with a C compiler available, there is no way you are getting this to run. You will have to search for a different way to handle your XML.
Just extracting a tarball only works when you have a pure-Perl module.
The easiest way to get a full Perl toolchain on Windows is to install Linux install the Strawberry Perl distribution. There's even a ZIP edition and a portable edition that can be installed on a thumb drive, no admin privileges required.
Your more immediate problem is that XML::XPath in version 1.13 seems to be a shoddy module with an unusual directory layout. The package you are trying to load is at XML-XPath-1.13/XPath.pm but should be at XML-XPath-1.13/lib/XML/XPath.pm. Why?
When you say use XML::XPath; this does two things. First, Perl searches for a file XML/XPath.pm in all #INC directories. Assuming you have something like
use FindBin;
use lib "$FindBin::Bin/lib/XML-XPath-1.13";
then perl would expect a file PROJECT/lib/XML-XPath-1.13/XML/XPath.pm which doesn't exist (where I'm using PROJECT as placeholder for the directory of your script).
Since the file PROJECT/lib/XML-XPath-1.13/XPath.pm does exist you could say use XPath;.
But then the second thing happens: The package is imported so that it can load subroutines or constants into your namespace. The use'd package name is now used as a class: XPath->import. However, the XPath.pm file does not contain the XPath package but the XML::XPath package, so there is no XPath class with an import method.
The import method call can be suppressed by providing an empty list in the use statement: use XPath ();.
Better than such hacks, you could use a more recent version of XML::XPath (version 1.13 is from 2003, but the newer version 1.42 is from 2007). Once you extract it you could use lib "$FindBin::Bin/lib/XML-XPath-1.42/lib" and then use XML::XPath;.
But this still won't work, because XML::XPath does use XML::Parser and you don't have that module installed. Now we are back to your main problem: XML::Parser needs to be compiled first because it contains a C extension, and also relies on an external library. Without a full toolchain you can't compile it.
First of all, you should properly install the module into lib rather than unzipping the distribution into lib.
Then, you'll need
use FindBin qw( $RealBin );
use lib "$RealBin/lib";
use XML::XPath qw( );
I'm trying to get the resolution,width,height of the images in the specific file.
I have the following code.
#use strict;
use Image::Info qw(image_info dim);
use File::List;
#perl2exe_include Image::Info::JPEG;
#perl2exe_include PerlIO;
my $file = <ImageFilePath>;
my $info = image_info($file);
my $res = $info->{resolution};
print "$$res[0]\n";
I have the Perl Version 5.16.3
I get the following error:
Can't locate Image/Info.pm in #INC (#INC contains: c:\program files\Perl\lib c:/program files/Perl/site/lib c:/program files/Perl/lib .) at Img_Res.pl line 3.
BEGIN failed--compilation aborted at Img_Res.pl line 3.
Can anyone give me the solution to this?
From the code part of question I am concluding that you are trying to create an executable using Perl2EXE, because you are using the line
#perl2exe_include Image::Info::JPEG;
and also assuming that you are running command
perl2exe c:\somepath\somescript.pl -o somescript.exe
The answer from #James Green is correct to an extent, however its incomplete (as in fails to explain his second bullet point).
You need to install "Image::Info" and any other modules that you are using (Use the answer from #James Green).
After installation, Open to windows explorer and locate the module that you just installed,
It will normally be in the following folders
"PERL_PATH\perl\lib"
"PERL_PATH\perl\site\lib"
"PERL_PATH\perl\vendor\lib"
Once you locate the module is installed in the one of the 3 locations above. Navigate to the location where Perl2EXE is installed.
PERL2EXE_PATH\perl2exe-XX.xx-Win\
Locate the folder with the current version of perl you are using. In your case the folder name should be
Win32-5.16.3 or Win64-5.16.3
Open the folder and locate the .conf file.
Edit the line with header libdir.
libdir=perl-Win32/site/lib;perl-Win32/lib;perl-Win32/vendor/lib;.
Ensure all the perl/lib directories are included in the search path.
Save it and rerun your command. This should work.
Sometimes even after all this the perl2exe command fails, this is due to the limitation of the program being able to decipher the qw command.
So to avoid this directly call the module (ex: use Module::Name;) in your code instead of using the qw.
You need to ensure you've done two things:
install the Image::Info module
make sure #INC includes the path to wherever you installed the module
I see you're on Windows, which means you're likely using either Strawberry Perl, or ActiveState's Perl. If you're using Strawberry Perl you should have some success following the directions on http://www.cpan.org/modules/INSTALL.html -- I believe ActiveState has its own built-in package manager, ppm, and to get started with that you'll want to look here: http://www.activestate.com/activeperl/ppm-perl-modules
I am currently trying to create/generate a CSV file using one of three classes:
use Class::CSV;
use Text::CSV;
use Text::CSV_XS;
Though when I try and run it, to check my code I come up with the same error message:
Can't locate Class/CSV.pm in #INC (#INC contains: C:/Per/site/lib C:/Perl/lib .) at C:\Users\<DIRECTORY> - <DIRECTORY>.file.pl line1
I have tried searching for the files though I haven't had any luck. Has anyone else come up against this problem? I have looking in the Directory and the CSV.pm file does exists.
Assuming that Class::CSV is installed on your system, your library search path is incomplete. (Your error message lists C:/Per/site/lib as a search lib, which looks like a typo for C:/Perl/site/lib, which you might want to look into.)
You need to locate the correct CSV.pm file where the library is located. For example, if it's found in:
C:/Perl/lib/foo/Class/CSV.pm
Then you have one of the following options.
Modify the environment for Perl or the invocation so that this is set (assuming my Windows skill haven't expired completely, someone feel free to edit and correct if I get the syntax wrong):
PERL5LIB=%PERL5LIB%;C:/Perl/lib/foo
You can use the -I option to perl to add the path:
perl -IC:/Perl/lib/foo my-app.pl
You can use the use lib command in the program itself to add the search path:
use lib 'C:/Perl/lib/foo';
use Class::CSV;
# etc.
You probably don't have these modules installed.
run this in your shell
perl -MCPAN -e shell
then run
install Class::CSV
I'm assuming that you found these classes on CPAN
You can simply run the following command
perl -MCPAN -e 'install Class::CSV'
to run
install Class::CSV in CPAN shell.
I have downloaded and installed a perl tool (lattice-tool).
But it is in my local directory.
While I'm running it says can't locate Directed.pm(a lib file) which is available in lib folder of my local directory.
I hope it will be set right if I set path variable. If so, how do I set it?
For use lib you have to use full path, and you are should not use relativ path like this.
use '../lib';#not working in all times.
Scenario: Your scripts in something/bin/prog.pl, your lib is something/lib/lib.pm.
If you use relativ path, you should call your program like this:
cd something/bin/ && ./prog.pl
If you would like to use relativ path, use FindBin to find your current path:
use FindBin;
use lib "$FindBin::Bin/../lib";#your lib realitv to your script
use lib $FindBin::Bin;#your current script full path
Then you could call your program from anywhere it will always find its lib realtiv to itself.
cd ~
something/bin/prog.pl# ti will use the correct lib
In my scripts, I have the following (which I'm sure can be improved, but it has worked thus far):
my $mydir; BEGIN { ($mydir) = ($0 =~ m#(.*)[/\\]#) or $mydir = '.'; }
use lib "$mydir/lib";
So the script tries to determine its own directory and then tells Perl to look for libraries within the lib subdirectory of that directory.
You need to add 'lib' to the directories perl searches for modules. You can do this with the -I flag:
perl -Ilib lattice-tool.pl
Use lib:
use lib 'lib';
lib also checks for architecture specific sub directories under lib to make sure machine-dependent libraries are loaded.
EDIT: Note that directories passed to lib are relative to your current working directory, so that if you want to execute your script from another location you should use use lib '/home/user1126070/lib'.
From perlvar:
The array #INC contains the list of places that the do EXPR , require, or use
constructs look for their library files. It initially consists of the arguments
to any -I command-line switches, followed by the default Perl library, probably
/usr/local/lib/perl, followed by ".", to represent the current directory. ("."
will not be appended if taint checks are enabled, either by -T or by -t .) If you
need to modify this at runtime, you should use the use lib pragma to get the
machine-dependent library properly loaded [...]
My OS-Distribution provides the rpm-package "perl-obexftp", which installs the Modul "OBEXFTP".
These are the files:
/usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi/OBEXFTP.pm
/usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi/auto/OBEXFTP
/usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi/auto/OBEXFTP/.packlist
/usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi/auto/OBEXFTP/OBEXFTP.bs
/usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi/auto/OBEXFTP/OBEXFTP.so
/var/adm/perl-modules/obexftp
I am using now a Perl which I have build from the source.
Is there a simple way to make this OBEXFTP-module accesseble to my Perlinstallation?
Choose one of
Add the following pragma to your code:
use lib '/usr/lib/perl5/vendor_perl/5.10.0';
Add that path to the PERL5LIB environment variable
Invoke your code with perl -I/usr/lib/perl5/vendor_perl/5.10.0 program
Rebuild perl so that path is in its baked-in #INC
Build the module yourself using your custom-built perl
For details, see perlrun.