【问题标题】:Why doesn't my Perl script find my module even after I adjust @INC with FindBin?为什么我使用 FindBin 调整 @INC 后,我的 Perl 脚本仍找不到我的模块?
【发布时间】:2020-08-24 06:23:20
【问题描述】:

我希望能够使用保存在我的源代码存储库的 lib 目录中的模块,并且我希望开发人员使用我正在编写的脚本的唯一先决条件是拥有一个标准 Perl 安装,但我不知道如何完成。

在我的脚本中,我有

use FindBin qw($Bin);
use lib "$Bin/lib"; # store non standard modules here
use Term::ANSIColor;
use Win32::Console::ANSI;
print Term::ANSIColor::colored("this should be in color\n", "bold red");

然后我将模块放在 ./lib 中。我验证了这是模块存在的实际位置(通过重命名它并导致它失败)。但是,即使模块位于任意 lib 目录中,似乎仍然需要 ppm 了解该模块。

如果没有先由 ppm “安装”,我无法让我的脚本在 lib 中找到/使用它。我想应该有某种解决方法。

我知道这可能是一个非典型的要求,但我的目标可能是非典型的。我只希望开发人员进行检查并立即使用一些脚本,而无需运行一些额外的命令或使用包管理器。

感谢您的任何见解。

编辑:我更新了一个完整的例子。我还意识到,如果我通过 ppm 卸载它(但将 pm 保留在引用的目录中),我可能必须更改我的语法,而我之前没有考虑过。所以也许我必须给出一个完整的路径或使用像 jheddings 或 BipedalShark 提议的要求(即,如果它没有“安装”,那么我必须使用“要求”并将“.pm”附加到它或使用一个 BEGIN 块。

如果是这样,那么我没有找到正确的语法。

编辑 2: 根据下面的评论,我意识到我可能有一个有缺陷的假设。我的理由是:如果我直接引用实际代码“.pm”,那么我应该能够在不使用包管理器的情况下使用它。也许情况并非如此,或者如果我想这样做,也许我必须以不同的方式来做。或者,我可能必须重构“.pm”中的代码。

编辑 3: 我认为我误解了一些事情。我的 IDE 中的错误消息“Compilation failed in require”,突出显示了我用来包含模块的行,以及控制台错误消息“Can't locate loadable object for module Win32::Console::ANSI”

我认为这是加载模块本身的问题,但这似乎是由模块本身试图加载的东西引起的问题。有趣的是,这只是一个问题,因为我没有使用 ppm install。

它正在寻找实际的模块。我能够通过注释掉问题行来验证这一点。

感谢您的帮助,但我将不得不花更多时间处理它。

【问题讨论】:

  • 你的问题毫无意义。除了作为安装程序之外,PPM 对任何事物都没有影响。当它“不起作用”时它会做什么?
  • 你为什么要谈论包管理器?您的脚本不应该关心模块是如何到达那里的。您真正的问题是不是您发布的内容?
  • lib/ 中有什么模块? lib/ 长什么样子?
  • 恕我直言,您可以使用PAR并将其编译为.exe。
  • @Keith:有更新吗?你找到问题了吗?

标签: perl module activeperl


【解决方案1】:

请参阅“无法找到模块的可加载对象...”下的perldoc perldiag

    (F) The module you loaded is trying to load an external library,
    like for example, "foo.so" or "bar.dll", but the DynaLoader module
    was unable to locate this library.  See DynaLoader.

你说得对,这个问题是由模块试图加载的东西引起的——这就是Dynaloader 所做的。但是,Win32::Console::ANSI 的文档没有提及任何外部库要求。

【讨论】:

  • 当我运行“ppm install bribes.org/perl/ppm/Win32-Console-ANSI.ppd”时,它还在“C:\Perl\site\lib\auto\Win32\Console\ANSI”中安装了一个我不知道并导致的 dll我沿着这条路走下去。我认为下午是唯一的下载,因此所有的混乱。
【解决方案2】:

您是否将模块路径结构保留在 lib 目录中?
即你的模块应该在路径$Bin/lib/Some/Module.pm

【讨论】:

  • 是的,这就是我的意思,我可以重命名它并导致它失败。我确定 lib 路径中的文件就是它正在使用的文件。谢谢。
  • 我现在意识到,如果我没有通过 ppm“安装”它,我可能不得不更改我的语法。我试过 require、use 和指定相对路径和绝对路径的 Begin 块还没有找到解决方案。
【解决方案3】:

来自perlfaq8How do I add the directory my program lives in to the module/library search path?的回复

您似乎做得对,但如果您希望获得帮助,您需要给我们更多信息。

当您运行该脚本时,@INC 中的结果是什么?放入调试行,如:

 BEGIN {
      use lib ...;
      print "INC is \@INC\n"; 
      }

检查该输出是否显示您期望的目录。如果没有,请从那里开始平分问题。

【讨论】:

    【解决方案4】:

    试试这个:

    BEGIN {
        use FindBin qw($Bin);
    }
    use lib "$Bin/lib"; # store non standard modules here
    

    【讨论】:

      【解决方案5】:

      我一直手动安装模块,它似乎工作。我只是将目录和文件复制到一个位置,然后像你展示的那样使用“use lib”指令。有时我错过了一个文件,我得到一个运行时错误,它正在寻找某个文件,我去 Internet 上找到该文件并将它放在正确的位置并且它可以工作。不确定您的设置发生了什么。这应该可以。

      我通常将 perl 模块与我的脚本放在同一目录中,然后:使用 lib "." 但我不知道这是否重要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-26
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2011-01-31
        • 2013-10-13
        • 1970-01-01
        • 2010-09-26
        相关资源
        最近更新 更多