Why I can't run perl from Textmate? - perl

#!/usr/bin/perl -w
use WWW::Mechanize;
print $WWW::Mechanize::VERSION."\n";
1) run from Textmate :
Can't locate WWW/Mechanize.pm in #INC (#INC contains:
/Applications/TextMate.app/Contents/SharedSupport/Bundles/Perl.tmbundle/Support
/Library/Perl/Updates/5.10.0
/System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0
/Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level
/Network/Library/Perl/5.10.0 /Network/Library/Perl
/System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.10.0 .) at
/Users/xxx/Development/test.pl line 2. BEGIN failed--compilation
aborted at /Users/xxx/Development/test.pl line 2.
2) run from terminal:
sh-3.2# perl test.pl<br>
1.64
What should I do?

It appears you installed WWW::Mechanize into a directory that isn't searched by default. Most likely, you have a PERL5LIB or other environment variable that adds that directory to Perl's search path, and for some reason that's not set in the environment TextMate provides.
Try running perl -V from the shell and from TextMate and see what the difference in search paths is. You can also add
print "$INC{'WWW/Mechanize.pm'}\n";
to your test script to find out where it's installed.

Related

Perl throws "Can't locate Config/YAML.pm in #INC"

I'm getting Can't locate Config/YAML.pm in #INC (you may need to install the Config::YAML module) while running a perl script.
Can't locate Config/YAML.pm in #INC (you may need to install the
Config::YAML module) (#INC contains: /etc/perl
/usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18
/usr/local/lib/site_perl .) at myperlscript line 8. BEGIN
failed--compilation aborted at myperlscript line 8.
Line 8 of the script shows use Config::YAML;.
I'm using Ubuntu and have installed the libdata-yaml-perl and libyaml-perl packages, but still am getting the same error. What else is needed?
Config::YAML requires a different package. Install the libconfig-yaml-perl package and the problem will be fixed.
As the error says, something is missing in #INC. If you do have the module installed (perldoc -l YAML::Tiny for example) it might be installed in a location that is not added to #INC (see How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?) for how it's constructed).
That means that there could be something wrong with environment variables: if for example PERL5LIB is not set (or not set correctly), it could also cause this error.
For example, if Perl is installed in /home/myusername/perl5, setting PERL5LIB="/home/myusername/perl5/lib/perl5" can fix this (e.g. in your ~/.profile, don't forget to log out and in).
For reference, here is what my Perl installation had autogenerated:
PATH="/home/myusername/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/myusername/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/myusername/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/myusername/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/myusername/perl5"; export PERL_MM_OPT;

Can't locate XML/LibXML.pm in #INC

I am trying to run script which uses XML/LibXML package.
But, XML/LibXML package is already installed. I ran following command:
perl -MXML::LibXML -e 1. it did not give any output, that means this package is installed.
when i ran my script. Following error occured.
Can't locate XML/LibXML.pm in #INC (#INC contains:
/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl
/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl
/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8
.). BEGIN failed--compilation aborted.
One more point to note is there is no directory "5.8.8" under /usr/lib64/perl5/site_perl/
Please suggest to overcome this issue.
There are three possibilities:
You have two installs of perl and you script is using the "wrong" one.
Either install XML::LibXML using the perl used by the script, or replace the script's shebang (#!) line with the output of the following:
perl -MXML::LibXML -le'print "#!".$^X'
Differences in the environment.
If XML::LibXML was installed in a nonstandard directory, it could be that PERL5LIB was used to communicate this to perl when you executed your test, but not when you run the script.
A permission issue.
This isn't very likely.
If the script is run as the same user as your test, it's not a permission issue.
If it is a permission issue, make sure the library directory is accessible to the user executing the script.

Can't locate *** in #INC

I install perl modules in ~/.local/perl5. Here's part of ~/.bashrc:
export PERL_LOCAL_LIB_ROOT="$HOME/.local/perl5";
export PERL_MB_OPT="--install_base $HOME/.local/perl5";
export PERL_MM_OPT="INSTALL_BASE=$HOME/.local/perl5";
export PERL5LIB="$HOME/.local/perl5/lib/perl5:$PERL5LIB";
export PATH="$HOME/.local/perl5/bin:$PATH";
I've installed CSS::Inliner with
$ cpan
cpan[1]> install CSS::Inliner
and I have Inliner.pm at:
~/.local/perl5/lib/perl5/CSS/Inliner.pm
But when I use it -- perl can't find it:
perl -e 'use Inliner'
gives:
Can't locate Inliner.pm in #INC (#INC contains:
/home/boris/.local/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
/home/boris/.local/perl5/lib/perl5 /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 .) at -e line 1. BEGIN failed--compilation
aborted at -e line 1.
why can't perl find the module?
Edit:
I'm trying to reproduce minimal working example given in documentation to CSS-Inliner:
use Inliner;
my $inliner = new Inliner();
$inliner->read_file({filename => 'myfile.html'});
print $inliner->inlinify();
If I use Inliner -- perl can't find it. If I
#!/usr/bin/perl
use CSS::Inliner;
my $inliner = new Inliner();
$inliner->read_file({filename => 'test.html'});
print $inliner->inlinify();
perl says
Can't locate object method "new" via package "Inliner"
(perhaps you forgot to load "Inliner"?) at ./1.perl line 5.
Edit 2:
Here's a minimal working example of CSS-Inliner:
#!/usr/bin/perl
use CSS::Inliner;
my $inliner = CSS::Inliner->new;
$inliner->read_file({filename => 'test.html'});
print $inliner->inlinify();
You should use the full module name in use and full class name when calling class methods:
use CSS::Inliner;
my $inliner = CSS::Inliner->new;
This could happen when you are not careful in installing modules. Once I simply copied the foo.pm into the official /usr/lib/perl5/site_perl directory. The foo.pm could be modules developed locally or third party. I did not pay attention to the umask. Files installed there are not readable by the world. When I use the module I will get the message saying: Cannot locate foo.pm in #INC(#INC contains /usr/lib/perl5/site_perl ....). Gee it is clearly there! Took me a while to check the file permission. Hope this may save some time for others who install their own modules. In make file you should use install -m 644 to make sure the installed module has read permission for others.

Trouble With CPAN Module

I've tried to install the WWW::Mechanize module with
'cpan WWW::Mechanize'
I get no errors on the 'use WWW::Mechanize' line which means its finding the files, but upon trying to instantiate it with:
$m = WWW::Mechanize->new();
I get the following problem:
Can't locate HTTP/Config.pm in #INC (#INC contains: /Library/Perl/Updates/5.10.0/darwin- thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at /Library/Perl/5.10.0/LWP/UserAgent.pm line 746.
I'm not exactly sure what is going on. I feel like I have all the neccessary dependencies, but I can't seem to find what this particular error means.
My script is empty besides the previously mentioned lines and
use strict;
use warnings;
Has anyone run into this?
try installing it with the following command (from the shell):
perl -MCPAN -e 'install WWW::Mechanize'
follow the installation process, and answer 'Y' where needed.

How do I set Perl's #INC for a CGI script?

I have the following, simplest Perl CGI script:
use strict;
use warnings;
use CGI();
use CGI::Carp qw(fatalsToBrowser);
use Template;
print CGI::header();
foreach(#INC) {
print "$_\n";
}
When called (http://[..]/cgi-bin/p.cgi) I am given the following error:
Can't locate Template.pm in #INC (#INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
BEGIN failed--compilation aborted at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
I made sure that Template is installed and indeed when running this program from shell it works (loads Template) and outputs:
Content-Type: text/html; charset=ISO-8859-1
/home/pistacchio/lib/perl5
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/home/pistacchio/lib/perl5/lib
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8
/usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8
/usr/lib/perl5/vendor_perl
/usr/lib/perl5/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/5.8.8
Template is installed in /home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ pwd
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ ls
auto perllocal.pod Template Template.pm
This directory is correctly listed in env and, as previously posted, in #INC. In #INC it is shown twice, so I even tried to pop it out before calling use Template, but without result. From env:
[pistacchio#web118 i386-linux-thread-multi]$ env
[..]
PERL5LIB=/home/pistacchio/lib/perl5:/home/pistacchio/lib/perl5/lib:/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[..]
Removing use Template gets rid of the problem.
The webserver doesn't run as your user, so its environment isn't your user environment. You can set that up in a variety of ways depending on your webserver. In Apache, you can use the SetEnv directive:
SetEnv PERL5LIB /path/to/your/libs
That then applies to everything under it. If you have it in a .htaccess file, for instance, it applies to everything under that directory.
If you can't do something like that, you're stuck setting the value of #INC in each script yourself with the lib pragma.
I would suggest adding the following to your CGI
use lib "/home/pistacchio/lib/" ;
The PERL5LIB env variable is presumably not available to CGI programs.
Edit What I meant, any value you have set in PERL5LIB from a shell will not be available.