"Undefined subroutine &HTML::Entities::decode_entities called" - perl

I'm getting the error
Undefined subroutine &HTML::Entities::decode_entities called`
using LWP::UserAgent, although the module is there, as well as the HTML::Parser module.
I suspect it has something to do with XS modules missing, since the function in question seems to be implemented in XS, but I am at a loss.

Recent versions of HTML::Entities depend on getting the decode_entities routine by loading the HTML::Parser module's XS component. Since the two modules are distributed together, this should not be a problem, but it's possible you have an older HTML::Parser version that didn't use XS instead (or multiple versions of HTML::Parser installed, with the wrong one being found first).
Check the $VERSION in HTML::Parser, look up that distribution on http://search.cpan.org/dist/HTML-Parser, and verify that distribution has the version of HTML::Entities that you have.

Are you missing this line:
use HTML::Entities;
From the HTML::Entities CPAN page, it should be used like this:
use HTML::Entities;
my $a = "Våre norske tegn bør &#230res";
decode_entities($a);
encode_entities($a, "\200-\377");
If you think there is something wrong with the HTML::Entities package, you can check the source on your system. From bash:
vim $(perldoc -l HTML::Entities)
Once the file is opened in your text editor, you can check that the subroutine is defined. I suspect that the package is correct though, it is more likely that the package isn't "used".
You can also test this at the command line to see if it works outside your program:
perl -MHTML::Entities -le 'print HTML::Entities::decode_entities( "Våre norske tegn bør &#230res" )'

Related

'use lib' can't find Perl module

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( );

Perl Par::Packer Can't find module issue

I have a perl program that uses WWW::Mechanize::Firefox on windows 7 32bit with strawberry perl.
It works fine with the command C:\>perl testcase.pl. When I compile it with C:\>pp -o testcase.exe testcase.pl it compiles with no errors.
When I run the testcase.exe it gives me the error:
Failed to connect to , Can't locate object method "setup" via package "MozRepl::Client" at MozRepl.pm line 224
The code I am using for testcase.pl is:
#!perl
use MozRepl;
use WWW::Mechanize::Firefox;
use warnings;
system('start firefox');
sleep(5);
$mech = WWW::Mechanize::Firefox->new;
Also note that a program without WWW::Mechanize::Firefox and MozRepl does work fine.
The problem has obviously been narrowed down to PAR::Packer not liking MozRepl, any idea what it might be?
PAR::Packer sometimes has a hard time identifying which modules need to be included in a PAR package in order to fulfill all of the requirements of the program you are trying to package.
It copes OK if the dependancies are loaded via plain 'use', or 'require' statements where the module to be loaded is a literal string, but it won't have much chance if the module is being loaded dynamically with something like:
require $myModuleToLoad;
Browsing the source code of MozRepl and related modules shows that they make heavy use of plugins loaded dynamically. I suspect that some of these are not being packaged.
You can manually specify module(s) to be included in the PAR package by adding -M Module::Name to the pp command line for each of the modules to be added (replacing Module::Name with the actual module name of course).
The hard part might be identifying which modules to include. One way to do this is to temporarily add something like this to the end of your script:
END { print "$_ -> $INC{$_}\n" foreach sort keys %INC; }
then run your script normally, not through PAR. It should list all the modules that were loaded. You can compare that with the actual modules present in the PAR package and add the missing ones using the -M option to pp.
You can see the modules inside your PAR file by opening it with an unzipping tool, such as 7zip. Or in Linux:
unzip -l {parfile}

install CPAN module ClearCase::CtCmd

I need to install the CPAN module ClearCase::CtCmd. I have downloaded the module CtCmd-1.09. After running the command perl Makefile.PL I am having the following errors:
perl Makefile.PL
Looking for ClearCase version 7 Found 7.1
Looking for gcc version 2.7 Found 3.4
Looking for SunOS 5.7 Found 5.8
Checking if your kit is complete...
Use of uninitialized value in chdir at /usr/local/lib/perl5/5.8.5/File/Find.pm line 741.
Use of chdir('') or chdir(undef) as chdir() is deprecated at /usr/local/lib/perl5/5.8.5/File/Find.pm line 741.
Looks good
Could not open 'CtCmd.pm': No such file or directory at /usr/local/lib/perl5/5.8.5/ExtUtils/MM_Unix.pm line 3079.
I mention that the perl version is v5.8.5. In the INSTALL file it is stated that "The ClearCase::CtCmd module requires Perl v5.6.1 or v5.8 or later."
What type of machine is this on? Solaris? Doesn't ClearCase come with its own version of Perl that already includes ClearCase::CtCmd?
Use of uninitialized value in chdir at /usr/local/lib/perl5/5.8.5/File/Find.pm line 741.
Use of chdir('') or chdir(undef) as chdir() is deprecated at /usr/local/lib/perl5/5.8.5/File/Find.pm line 741.
Looks good
File::Find is a standard Perl module. The uninitialized value in chdir does not look good.
Could not open 'CtCmd.pm': No such file or directory at /usr/local/lib/perl5/5.8.5/ExtUtils/MM_Unix.pm line 3079.
ExecUtils/MakeMaker is calling ExtUtils/MM_Unix.pm and is trying to write your Makefile. I have a feeling it's suppose to locate where CtCmd.pm is located from File::Find and with File::Find failing, MakeMaker can't create the Makefile.
I'm looking at the Makefile.PL and see that it requires $ATRIA_ROOT to be set, or otherwise, it's inferred as being at /opt/rational/clearcase. Could this have something to do with it?
No. Doesn't look like it. Otherwise, you wouldn't have gotten the report on the ClearCase version. And, I guess the system is Solaris because that's the only place where the gcc version is being searched.
I think it's time to do a bit of munging in the Makefile.PL program to see what it's doing. I notice in line #218 is WriteMakefile(%opts); I would add a little routine to print out this %opts subroutine (probably using warn instead of print). This subroutine is from ExtUtils::MakeFile which actually writes the Makefile. It might give you a clue to what's going on.
Unfortunately, the problem looks like it has to do with the way ExtUtils::MakeMaker is working. Using Perl 5.8.5 means you have an older, buggier version of ExtUtils::MakeMaker. You can look at the release notes of ExtUtils::MakeMaker and see if that offers you any clue. Perl 5.8.5 is no longer supported. It's a very, very old version of Perl.

What is here the recommended way the get rid of the "v-string in use/require non-portable" warning?

A module requires at least Perl 5.10.0.
When I use this module with Perl version 5.10.0 I get the warning:
v-string in use/require non-portable at ... (line of "use 5.10.0;").
In Perl 5.10.1 this warning is removed.
What would be the recommended way to avoid the warning:
- change all "use 5.10.0" in the distro to "use 5.010_000;"
- add "no warnings 'portable';" to the module
- leave it to the user of Perl 5.10.0 to add "no warnings 'portable';"
- Increase the smallest required version to 5.10.1.
perl -wE 'use 5.10.0; say $^V'
# v-string in use/require non-portable at -e line 1.
# v5.10.0
If you want anything from 5.10.0 and later, you don't need to specify a minor version:
use v5.10;
You might consider using at least 5.10.1, which had some significant changes to the earlier minor version (including fixing your warning):
use v5.10.1;
But, give us a sample program, show use which Perl you're using and all that other stuff.

How do I use a dependency on a Perl module installed in a non-standard location?

I need to install two Perl modules on a web host. Let's call them A::B and X::Y. X::Y depends on A::B (needs A::B to run). Both of them use Module::Install. I have successfully installed A::B into a non-system location using
perl Makefile.PL PREFIX=/non/system/location
make; make test; make install
Now I want to install X::Y, so I try the same thing
perl Makefile.PL PREFIX=/non/system/location
The output is
$ perl Makefile.PL PREFIX=/non/system/location/
Cannot determine perl version info from lib/X/Y.pm
*** Module::AutoInstall version 1.03
*** Checking for Perl dependencies...
[Core Features]
- Test::More ...loaded. (0.94)
- ExtUtils::MakeMaker ...loaded. (6.54 >= 6.11)
- File::ShareDir ...loaded. (1.00)
- A::B ...missing.
==> Auto-install the 1 mandatory module(s) from CPAN? [y]
It can't seem to find A::B in the system, although it is installed, and when it tries to auto-install the module from CPAN, it tries to write it into the system directory (ignoring PREFIX). I have tried using variables like PERL_LIB and LIB on the command line, after PREFIX=..., but nothing I have done seems to work.
I can do make and make install successfully, but I can't do make test because of this problem. Any suggestions?
I found some advice at http://servers.digitaldaze.com/extensions/perl/modules.html to use an environment variable PERL5LIB, but this also doesn't seem to work:
export PERL5LIB=/non/system/location/lib/perl5/
didn't solve the problem.
The answer is local::lib, but you probably already know that :)
OK, the following prescription did it:
perl Makefile.PL --skipdeps --no-manpages PREFIX=/non/system/location INSTALLSITELIB=/non/system/location/lib INSTALLSITEBIN=/non/system/location/bin INSTALLMAN1DIR=/non/system/location/man/man1 INSTALLMAN3DIR=/non/system/location/man/man3
This is just "monkey see monkey do" but now make test works.
The --skipdeps option here suppresses a convenient feature/exasperating problem with Module::Install where it tries to use CPAN.pm to download missing modules.
The --no-manpages is supposed to stop it installing man pages but it doesn't work.
Because this is the top link i thought i'd update with my experience (which has taken a while to get working, hence updating the 7 year old post).
first run perl -le 'print join $/, #INC'
add (note, no / at the end!!)
export PERL5LIB=/nonstddir/scripts/modules/lib/site_perl:/nonstddir/scripts/modules/lib
run perl -le 'print join $/, #INC' make sure the new dirs are added. this makes it work. if you add a / at the end of the path, the INC entry will look weird and wrong. Mine had a // in the middle.
When done and working, mine looks like
/nonstddir/scripts/modules/lib/site_perl/5.8.4/sun4-solaris-64int
/nonstddir/scripts/modules/lib/site_perl/5.8.4
/nonstddir/scripts/modules/lib/site_perl
/nonstddir/scripts/modules/lib/sun4-solaris-64int
/nonstddir/scripts/modules/lib
/usr/perl5/5.8.4/lib/sun4-solaris-64int
/usr/perl5/5.8.4/lib
/usr/perl5/site_perl/5.8.4/sun4-solaris-64int
/usr/perl5/site_perl/5.8.4
/usr/perl5/site_perl
/usr/perl5/vendor_perl/5.8.4/sun4-solaris-64int
/usr/perl5/vendor_perl/5.8.4
/usr/perl5/vendor_perl