【问题标题】:'use lib' can't find Perl module“使用库”找不到 Perl 模块
【发布时间】:2017-08-17 04:18:28
【问题描述】:

我在 Windows 7 上,我下载了一个名为 XML::XPathCPAN module,我想在我编写的脚本中使用它。

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

所以为了使用该模块,我去了CPAN网站,下载了该模块的.tar.gz文件,并将其解压缩到我项目中的lib文件夹中。我这样做是因为this guide 建议我可以在我的脚本上下文中使用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 运行此脚本时,脚本失败并出现以下错误:

无法在 test.pl 第 10 行通过包“XML::XPath”找到对象方法“new”(也许您忘记加载“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。

【问题讨论】:

  • 也许您忘记加载“XML::XPath”? - 那么您的use XML::XPath 呢? use lib 仅指定要查找的路径。
  • 那个模块的目录结构看起来有点怪,即使你加了use XML::XPath;也行不通。 1.13 版本是 2003 年的,但幸运的是,有更新的版本具有正确的目录结构:(例如,一个月前的 1.42)。
  • @SteffenUllrich 我已将use XML::XPath; 添加到我的test.pl 脚本中(在第4 行,在我的use lib 参考下方),但现在我收到与Perl 在@ 中查找相关的错误987654347@ 用于脚本,我无法修改@INC。我已经更新了我的问题以反映这一点。
  • 再深入一点,似乎 XML::XPath 依赖于需要编译的 XML::Parser 模块。除非您有完整的 Perl 工具链可用(即可以编译 C 代码并安装模块),否则您无法使用此模块。仅提取 tarball 仅适用于纯 Perl 模块。
  • @amon 该模块确实存在,它位于我项目的lib/XML-XPath-1.13/XPath/ 目录中。你能详细说明为什么我不能使用它吗?

标签: perl


【解决方案1】:

这是行不通的。 XML::XPath 依赖于需要编译的 XML::Parser 模块。由于您没有可用的 C 编译器的完整工具链,因此您无法运行它。您将不得不寻找一种不同的方式来处理您的 XML。

仅当您拥有纯 Perl 模块时,仅提取 tarball 才有效。

在 Windows 上获得完整的 Perl 工具链的最简单方法是安装 Linux 安装 Strawberry Perl 发行版。甚至还有 ZIP 版和便携版,可以安装在 U 盘上,无需管理员权限。


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

当您说use XML::XPath; 时,它会做两件事。首先,Perl 在所有@INC 目录中搜索文件XML/XPath.pm。假设你有类似的东西

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 扩展,并且还依赖于外部库。如果没有完整的工具链,您将无法编译它。

【讨论】:

  • 非常感谢您清晰而说明性的答案!果然,use XPath 确实解决了最初的 XPath @INC 错误,就像你说的那样 - 但有趣的是,同样的解决方案在 XPath.pm 本身和 @987654347 上并不能更深入地工作@。所以我相信我遇到了一些复杂的基于约定的 Perl 包管理问题。不幸的是,我“死守权利”使得 StrawberryPerl 在我的情况下不是一个选择,但这个(和安装 Linux)是一个很好的建议。
  • Re "在 Windows 上获得完整 Perl 工具链的最简单方法是安装 Linux 安装 Strawberry Perl",或者如果您正在使用,则只需使用 cpan ActivePerl。
【解决方案2】:

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

那么,你需要

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

use XML::XPath qw( );

【讨论】:

  • 如问题所述,由于我无法控制的因素,我无法使用 PPM 等适当的包管理实用程序。我下载了物理的.pm 文件——理论上我不应该只使用它吗?
  • 我从未提及ppm(或任何其他包管理实用程序)。我不相信ppm 让您指定要安装模块的位置。 (如果是这样,那么即使您错误地声明了其他内容,您也可以使用 ppm..)
  • 你能解释一下“你应该正确安装模块”的意思吗?我现在只使用 Perl 几个星期了。我认为“正确安装模块”意味着使用包管理器或make。两者都对我不可用。您是说仅按原样从 CPAN 下载软件包还不够吗?
  • Re "我都无法使用。",显然是错误的,因为您可以运行任意 Perl 代码。
  • 有个窍门:你也可以在不同的机器上使用完全相同的perl来安装模块,但是你复制@的内容而不是make installBuild install 987654332@ 转为C:/Sandbox。这基本上就是 ppm 所做的。
猜你喜欢
  • 1970-01-01
  • 2020-01-25
  • 2012-08-13
  • 2017-09-17
  • 2015-05-27
  • 1970-01-01
  • 2019-10-08
  • 1970-01-01
  • 2013-03-06
相关资源
最近更新 更多