0

除非真的需要,否则我一直在我的程序中随意使用 .pm 文件而没有真正使用包。从本质上讲,我只会在 .pm 中有通用例程,并且在使用时它们将成为 main 的一部分(.pm 将没有包或 Exporter 之类的......只是一堆例程)。

然而,前几天我遇到了一种情况,我想我知道发生了什么以及为什么,但我希望从这里的专家那里得到一些关于最佳实践以及如何解决这个问题的指导。本质上,应该始终使用包吗?当我只想将常用例程吸收到 main(或父模块/包)中时,我应该“做”文件吗?Exporter 真的是处理这一切的方法吗?

这是我遇到的示例代码(我不会发布原始代码,因为它有数千行......这只是问题的本质)。

pgm1.pl:

use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;

下午 1 点:

package PM1;
require Exporter;
@ISA=qw(Exporter);
@EXPORT=qw(pm1sub1);
use Data::Dump 'dump';
use PM2;
&pm2sub1;
sub pm1sub1 {
    print "pm1sub1 from caller ",dump(caller()),"\n";
    &pm2sub1;
}
1;

下午 2 点:

use Data::Dump 'dump';
sub pm2sub1 {
    print "pm2sub1 from caller ",dump(caller()),"\n";
}
1;

本质上,我已经使用 PM2.pm 和它的 &pm2sub1 子程序有一段时间了。然后我在某个时候写了 PM1.pm,它也需要 PM2.pm 的例程。然而,在这样做时,PM2.pm 的模块被吸收到 PM2.pm 的包中,然后 Pgm1.pl 不能做同样的事情,因为 PM2.pm 已经被使用了。

此代码将产生

Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4.
pm2sub1 from caller ("PM1", "PM1.pm", 7)
main

但是,当我在 Pgm1.pl 中像这样交换使用语句时

use PM2;
use PM1;
print "main\n";
&pm2sub1;
&pm1sub1;

... perl 将允许 PM2.pm 的模块进入 main,但不允许进入 PM1.pm 的包:

Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7.
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2.
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2.

所以,我认为我可以通过在我的所有模块中对包和导出器保持虔诚来解决这个问题。麻烦的是,PM2.pm 已经在很多其他程序中使用,所以要确保我没有破坏任何东西,这将是大量的回归测试。

想法?

4

3 回答 3

4

请参阅我对库文件和模块之间有什么区别的回答?.

仅对模块(通常带有 的文件)使用require(因此)。对于“库”(通常没有 的文件),使用.usepackage.pmpackage.pldo

更好的是,只使用模块!

于 2012-07-03T18:13:13.697 回答
3

use不会多次加载同一个文件。但是,它import每次都会调用目标包的 sub 。您应该将您的 PM2 格式化为适当的包,以便use可以从那里找到它的import并将其导出功能到请求者的命名空间。

(或者您可以通过完全限定其名称将您的导入功能潜入适当的包中,但不要这样做。)

于 2012-07-03T18:17:34.387 回答
0

你只是在寻找这样安排你的代码的麻烦。给每个模块一个包名(命名空间),然后完全限定对其函数的调用,例如PM2::sub1()调用sub1PM2。您已经用包名命名了函数(pm2sub1);以正确的方式执行此操作需要两个额外的字符 ( ::),然后您也无需为 Exporter 操心。

于 2012-07-03T21:39:44.847 回答