'use lib'找不到Perl模块

时间:2017-08-16 19:21:38

标签: perl

我在Windows 7上,我下载了一个名为XML::XPath的{​​{3}},我想在我编写的脚本中使用它。

我无法在我的机器上修改@INC,我无法在我的机器上修改环境变量,我无法在我的机器上运行make,而且我无法在我的机器上使用包管理器。

因此,为了使用该模块,我访问了CPAN网站,下载了模块的.tar.gz文件,并将其解压缩到我项目中的lib文件夹中。我这样做是因为CPAN module建议我可以在脚本的上下文中使用use lib来引用下载的模块:

  

在脚本中添加一个use lib语句会将该目录添加到该特定脚本的@INC中。无论是谁以及在什么环境中运行它。

我的脚本名为test.pl。我正在尝试使用XML::XPath模块来解析名为test.xml的XML文件。以下是我的目录结构示例:

C:/
  → sandbox/
      test.pl
      test.xml
    → lib/
      → XML-XPath-1.13/
          XPath.pm
        → XPath/
            XMLParser.pm
            (etc.)

这是我的test.pl脚本:

#!/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");
}

当我使用perl test.pl运行此脚本时,脚本失败并显示以下错误:

  

无法通过包“XML :: XPath”找到对象方法“new”(也许你忘了在test.pl第10行加载“XML :: XPath”?)。

我可以使用use lib解决此错误吗?

修改

当我将use XML::XPath;添加到我的test.pl脚本时,就这样:

#!/usr/bin/perl
use strict;
use warnings;
use lib qw("C:/sandbox/lib/XML-XPath-1.13");

我收到如下错误:

  

无法在@INC

中找到XML / XPath.pm

但如上所述,我无法在机器上修改@INC或重新编译Perl。

2 个答案:

答案 0 :(得分:3)

这不起作用。 XML :: XPath依赖于需要编译的XML :: Parser模块。由于您没有可用的C编译器的完整工具链,因此您无法运行此工具。您将不得不搜索另一种处理XML的方法。

只有在拥有纯Perl模块时才提取tarball。

在Windows上获取完整Perl工具链的最简单方法是安装Linux 安装Strawberry Perl发行版。甚至可以在拇指驱动器上安装ZIP版和便携版,无需管理员权限。

您更直接的问题是版本1.13中的XML :: XPath似乎是一个带有异常目录布局的伪劣模块。您尝试加载的软件包位于XML-XPath-1.13/XPath.pm,但应位于XML-XPath-1.13/lib/XML/XPath.pm。为什么呢?

当你说use XML::XPath;时,这会做两件事。首先,Perl在所有XML/XPath.pm目录中搜索文件@INC。假设你有像

这样的东西
use FindBin;
use lib "$FindBin::Bin/lib/XML-XPath-1.13";

然后perl会期望一个文件PROJECT/lib/XML-XPath-1.13/XML/XPath.pm不存在(我使用PROJECT作为脚本目录的占位符)。

由于文件PROJECT/lib/XML-XPath-1.13/XPath.pm确实存在,您可以说use XPath;

然后第二件事发生了:导入包,以便它可以将子例程或常量加载到命名空间中。 use'd包名称现在用作类:XPath->import。但是,XPath.pm文件不包含XPath包,而是XML::XPath包,因此没有XPath类使用import方法。

可以通过在use语句中提供一个空列表来抑制导入方法调用:use XPath ();

比这些黑客更好,你可以使用更新版本的XML :: XPath(版本1.13来自2003,但较新版本1.42来自2007)。提取后,您可以use lib "$FindBin::Bin/lib/XML-XPath-1.42/lib"然后use XML::XPath;

但是这仍然不起作用,因为XML::XPath执行use XML::Parser并且您没有安装该模块。现在我们回到您的主要问题:XML :: Parser需要首先编译,因为它包含C扩展,并且还依赖于外部库。没有完整的工具链,你就无法编译它。

答案 1 :(得分:-1)

首先,您应该将模块正确安装到lib而不是将分发解压缩到lib

然后,你需要

use FindBin qw( $RealBin );
use lib "$RealBin/lib";

use XML::XPath qw( );