为什么模块可以自行编译,但从其他地方使用时会失败?

发布于 2024-08-21 00:34:24 字数 529 浏览 7 评论 0原文

我有一个 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.

rebat-report-status 的前几行是

...
3 use Rebat;
4 use Rebat::Store;
5 use strict;
...

I have a Perl module that appears to compile fine by itself, but is causing other programs to fail compilation when it is included:

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.

The first few lines of rebat-report-status are

...
3 use Rebat;
4 use Rebat::Store;
5 use strict;
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

躲猫猫 2024-08-28 00:34:24

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


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;

$ perl m1.pl
Attempt to reload M1::M2 aborted.
BEGIN failed--compilation aborted at m1.pl line 3.

如果您只是删除 m1.pl 中的 use M1::M2 行,代码将编译(并打印 42)。就您而言,您可能不需要在程序中显式使用Rebat::Store

Edit (for posterity): Another reason for this to occur, and perhaps the most common reason, is that there is a circular dependency among the modules you are using.


Look in Rebat/Store.pm for clues. Your log says attempt to reload was aborted. Maybe Rebat already imports Rebat::Store, and Rebat::Store has some package-scope check against being loaded twice.

This code demonstrates the kind of situation I mean:

# 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;

$ perl m1.pl
Attempt to reload M1::M2 aborted.
BEGIN failed--compilation aborted at m1.pl line 3.

The code will compile (and print 42) if you just remove the use M1::M2 line in m1.pl. In your case, you might not need to explicitly use Rebat::Store in your program.

云裳 2024-08-28 00:34:24

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.

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文