看看程序package MyCommonPkg.pm
,看看它说了什么。它有这样的东西吗?
package MyCommonPkg;
use Exporter qw(import); # Might be "require" and not "use"
our @EXPORT = qw(thisSubroutineIsNotDefinedAnywhereElse);
语法可能有点不同。您应该看到的主要内容是package
语句,它正在使用Exporter
并且@EXPORT
数组中包含您的子例程的名称。
正在发生的是命名空间冲突。您的包正在定义您正在定义的相同子例程。
为了防止这种情况发生,Perl 使用了命名空间。默认情况下,您的命名空间是main
. package
但是,假设包使用该命令定义自己的单独同名。
子例程或变量的完整名称空间是名称空间后跟一个双冒号,然后是子例程或变量名称。例如,如果您查看File::Find,您将看到对变量$File::Find::name
和的引用$File::Find::dir
。这些是变量$name
和名称空间下的包$dir
内。File/Find.pm
File::Find
为了让您更轻松,包可以将它们的变量和子例程导出到您的主命名空间中。例如,如果我使用File::Copy,O 可以这样做:
...
use File::Copy
...
copy ($file, $to_dir);
代替:
...
use File::Copy
...
File::Copy::copy ($file, $to_dir);
如果您查看File/Copy.pm
,您将看到以下内容:
package File::Copy;
...
our(@ISA, @EXPORT, @EXPORT_OK, $VERSION, $Too_Big, $Syscopy_is_copy);
...
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(copy move);
package File::Copy;
定义了一个命名空间。和允许包require Exporter;
将@ISA = qw(Exporter)
子例程和变量导出到主命名空间。@EXPORT
自动将andcopy
子move
例程导入到主 命名空间,不管你是否想要它们!
最后一点非常重要。它现在被认为是不礼貌的使用@EXPORT
。相反,您应该使用@EXPORT_OK
which 要求您列出要使用的子例程。像Scalar::Util这样的更现代的软件包可以做到这一点。
这么几件事。首先,你MyCommonPkg
有没有package MyCommonPkg;
声明。如果没有,它应该。这可以防止包子例程和变量以讨厌的方式影响您的程序。然后,您可以使用@EXPORT
或@EXPORT_OK
。
如果MyCommonPkg
确实有一个package
声明,它是否使用@EXPORT
?如果是这样,您有几种方法可以避免此问题:
- 忽略警告。这只是一个警告。既然您知道您正在重新定义子程序,并且您想使用您对子程序的定义,请忽略它。
您可以这样做以在重新定义子例程时关闭警告:
use MyCommonPkg;
no warnings qw(redefine);
sub thisSubroutineIsNotDefinedAnywhereElse {
...
}
use warnings qw(redefine);
- 使用
require MyCommonPkg;
而不是use MyCommonPkg;
. 这将防止将任何子例程或变量导入您的命名空间,包括您想要使用的那些。假设MyCommonPkg
定义了四个子例程:thisSubroutineIsNotDefinedAnywhereElse
、foo
、bar
和barfoo
。使用这些子程序中的任何一个。
你需要这样做:
my $answer = MyCommonPkg::foo( $input );
不好玩。
像这样:
use MyCommonPkg qw(foo bar);
在这种情况下,只有子程序foo
和bar
被导出。子例程thisSubroutineIsNotDefinedAnywhereElse
并barfoo
不会导出到您的环境中。