为什么模块本身编译但在从其他地方使用时会失败?

chr*_*ibe 4 perl perl-module

我有一个Perl模块似乎可以自行编译,但是在包含它时导致其他程序编译失败:

me@host:~/code $ perl -c -Imodules modules/Rebat/Store.pm
modules/Rebat/Store.pm syntax OK
me@host:~/code $ perl -c -Imodules bin/rebat-report-status
Attempt to reload Rebat/Store.pm aborted
Compilation failed in require at bin/rebat-report-status line 4.
BEGIN failed--compilation aborted at bin/rebat-report-status line 4.
Run Code Online (Sandbox Code Playgroud)

前几行rebat-report-status

...
3 use Rebat;
4 use Rebat::Store;
5 use strict;
...
Run Code Online (Sandbox Code Playgroud)

mob*_*mob 9

编辑(后代):发生这种情况的另一个原因,也许是最常见的原因,是您正在使用的模块之间存在循环依赖关系.


寻找Rebat/Store.pm线索.您的日志表示尝试重新加载已中止.也许Rebat已经导入了Rebat::Store,并且Rebat::Store有一些包装范围检查反对加载两次.

这段代码演示了我的意思:

# m1.pl:
use M1;
use M1::M2;
M1::M2::x();

# M1.pm 
package M1;
use M1::M2;
1;

# M1/M2.pm
package M1::M2;
our $imported = 0;
sub import {
    die "Attempt to reload M1::M2 aborted.\n" if $imported++;
}
sub x { print "42\n" }
1;
Run Code Online (Sandbox Code Playgroud)
$ perl m1.pl
Attempt to reload M1::M2 aborted.
BEGIN failed--compilation aborted at m1.pl line 3.
Run Code Online (Sandbox Code Playgroud)

如果您只删除该use M1::M2行,代码将编译(并打印42)m1.pl.在您的情况下,您可能不需要明确地use Rebat::Store在您的程序中.

  • 事实上,问题在于Rebat.pm和Rebat/Store.pm之间新引入的循环依赖性 (3认同)

Eug*_*ash 5

perldoc perldiag

 Attempt to reload %s aborted.
           (F) You tried to load a file with "use" or "require" that failed to
           compile once already.  Perl will not try to compile this file again
           unless you delete its entry from %INC.  See "require" in perlfunc
           and "%INC" in perlvar.
Run Code Online (Sandbox Code Playgroud)