package MyModule;
use strict;
use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = ();
@EXPORT_OK = qw(func1 func2);
%EXPORT_TAGS = ( DEFAULT => [qw(&func1)],
Both => [qw(&func1 &func2)]);
sub func1 { return reverse @_ }
sub func2 { return map{ uc }@_ }
1;
首先,我们将通过声明 "package" 名字来获得一个名字空间。这将确保模块中的方法与变量,和调用他们的代码所分隔开来。 use strict在模块中是一个非常好的做法,这将使Perl对使用全局变量做出一定的约束。
我们需要用Exporter模块来将我们的函数从MyModule::namespace输出到main::namespace,让使用MyModule的程序可以使用这些函数。
为了use strict,我们必须使用use vars来声明一些变量。当然,在5.6版本以上我们还可以使用our来声明变量。
我们现在设置一个$VERSION数值,然后通过使用@ISA来使得Exporter成为MyModule的一部?。想要了解@ISA是什么以及如何使用等细节,请参考"perlboot"。 @EXPORT包含了我们需要默认输出的函数列表。在这里,它是空的。一般来说,你通过默认的使用@EXPROT输出的越少越好。因为调用该模块的程序中,有可能存在与其中函数相之冲突的函数或者代码。如果程序需要调用某个指定的函数,那么,就请就让它主动请求。 @EXPORT_OK包含了我们在调用时需要输出的函数列表,我们只输出了&func1和&func2,这种方法要优先于盲目地使用@EXPORT来输出函数。你也可以输出像$CONFIG这样全局的、不是用my定义的字义范畴的变量。(可参考用 "our" 或者 use vars来声明全局变量) %EXPORT_TAGS.为了方便起见,我们定义了两套输出标签。‘:DEFAULT’标签只输出&func1;‘:Both’标签则输出&func1和&func2。这个哈希表存储指向数组引用的标签。注意:在这里的数组是匿名的。
最后,我们需要在模块结尾加上一个“1;”。因为当perl装载一个模块时,它会实现查看这个模块是否能在最后返回一个真值,并且据此判断该模块是否已装载成功。当然,你可以在最后面添加任何真值(参看 "Code::Police" ),但其中1是最方便的。
MySciprt.pl(使用MyModule的一个例子)
#!/usr/bin/perl -w
use strict;
# you may need to set @INC here (see below)
my @list = qw (J u s t ~ A n o t h e r ~ P e r l ~ H a c k e r !);
# case 1
# use MyModule;
# print func1(@list),"\n";
# print func2(@list),"\n";
# case 2
# use MyModule qw(&func1);
# print func1(@list),"\n";
# print MyModule::func2(@list),"\n";
# case 3
# use MyModule qw(:DEFAULT);
# print func1(@list),"\n";
# print func2(@list),"\n";
# case 4
# use MyModule qw(:Both);
# print func1(@list),"\n";
# print func2(@list),"\n";
正如上面所见,我们在MyScript.pl中使用了MyModule。把中间的注释符号都去掉来看看会发生什么。一次都去掉即可。 Case 1: 因为我们的模块默认什么都没有输出(没有输出&func1和&func2),所以我们会得到一个他们在main:: namespace中不存在的错误。 Case 2: 这个运行正常。我们让模块输出了&func1,于是我们可以正常使用它。尽管我们没有输出&func2,但是我们使用的是 &func2完整的包路径,所以它也可以正常工作。 Case 3: ‘:DEFAULT’标签应该输出&func1,所以你应该希望返回一个缺少&func2函数的错误。但事实上perl却偏偏找上了&func1的麻烦(错误信息提示未定义&func1函数)。恩,这里怎么了呢?原来,DEFAULT这个标签名字是特殊的,在我们的模块中,%EXPORT_TAGS哈希表它会被自动设置成这样DEFAULT=>\@EXPROT.也就是说,DEFAULT默认导出的是来自@EXPROT数组的函数。 Case 4: 我们指定通过‘:Both’标签实现两个函数都输出,他实现了。 *关于@INC的注意事项* 当你提交一个use MyModule的时候,就会指示perl去搜索@INC数组中是否有此模块名。@INC通常包含: