我一直在我的程序中使用.pm文件,除非真的需要,否则没有真正使用包。本质上,我只是在.pm中有常见的例程,当使用时它们会成为main的一部分(.pm没有包或者Exporter之类的东西......只是一堆例程)。
然而,前几天我遇到了一个情况,我想我知道发生了什么以及为什么,但我希望能从这里的专家那里得到一些关于最佳实践以及如何解决这个问题的指导。从本质上讲,应该始终使用包吗?当我只想要将常用例程吸收到main(或父模块/包)时,我应该“执行”文件吗?出口商真的能够处理所有这些吗?
这是我遇到的示例代码(我不会发布原始代码,因为它是成千上万行...这只是问题的本质)。
Pgm1.pl:
use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;
PM1.pm:
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;
PM2.pm:
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.
所以,我认为我可以通过在所有模块中对包和Exporter进行宗教信仰来解决这个问题。麻烦的是,PM2.pm已经在很多其他程序中使用了,所以要进行大量的回归测试以确保我没有破坏任何东西。
想法?
答案 0 :(得分:4)
请参阅my answer至What is the difference between library files and modules?。
仅对模块(package
的文件,通常是.pm
)使用require
(以及use
)。对于“图书馆”(没有package
的文件,通常为.pl
),请使用do
。
更好的是,只使用模块!
答案 1 :(得分:3)
use
不会多次加载同一个文件。但是,它每次都会调用目标程序包的import
子目录。您应该将PM2格式化为正确的包,因此use
可以从那里找到它的import
并将函数导出到请求者的命名空间。
(或者您可以通过完全限定其名称将您的导入功能隐藏到正确的包中,但不要这样做。)
答案 2 :(得分:0)
你只是在麻烦地安排你的代码。为每个模块提供一个包名(命名空间),然后完全限定对其函数的调用,例如PM2::sub1()
在sub1
包中致电PM2
。您已经使用包名称命名函数(pm2sub1
);这是两个额外的字符(::
),以正确的方式做到这一点,然后你也不需要打扰出口商。