起源
最近在工作中需要一些Perl脚本,发现目前项目中脚本的公共功能的复用做得很差,并且现存的复用脚本也只是使用require "/your/path/your_script.pl";简单的引用,并没编写成模块(.pm),安装到@INC目录中。于是就有了这篇博文。在介绍模块编写方法之前,我们先来说说两种加载模块的方式。
模块加载方式
加载模块可以使用require和use关键字。
两者的区别
require是运行时加载,use是编译时加载。
require可以指定路径,use只会从@INC中查找模块,找不到则会编译失败。
require加载一定在当前命名空间,use可以不污染当前命名空间。
use其实将相当于下面的代码
1 2
| require ModuleName; import ModuleName::(@EXPORT);
|
模块的编写
使用import函数导出变量和函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
package Some::Module;
use strict; use warnings;
no strict 'refs';
my $var1 = 513;
sub import { *{caller() . "::fun1"} = \&fun1; *{caller() . "::var1"} = \$var1; }
sub fun1 { print "I'm fun1."; }
1;
use strict; use warnings; use 5.010;
BEGIN { push(@INC, "/your/module/path"); }
use Some::Module;
say $var1;
&fun1();
|
运行test.pl将会有以下输出
import的导出方式,具体讲解参见Advanced Perl Programming(2nd Edition by Simon Cozens) — Chapter 1. Advanced Techniques
使用Exporter模块导出变量和函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
package Some::Module;
use strict; use warnings;
use Exporter; our @ISA = qw(Exporter);
our @EXPORT = qw($var1 func1);
my $var1 = 513; sub fun1 { print "I'm fun1."; }
1;
|
Exporter的导出方式,这里只是使用了最简答的@EXPORT数组,还有其他的使用方法参见Exporter文档。
面向对象的模块编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package Some::Module;
use strict; use warnings;
sub new { my ($class, @args) = @_; my $self = { @args, name => "Tom", age => 18 } bless $self, $class; }
sub getName { my $self = shift; return $selft->{name}; }
sub setName { my ($self, $name) = @_; $self->{name} = $name; }
sub getExt { my ($self, $ext) = @_; return $self->{$ext}; }
use strict; use warnings; use 5.010;
BEGIN { push(@INC, "/your/module/path"); }
use Some::Module;
my $obj = Some::Module->new(phone => "3478-1321"); say "Old name: " . $obj->getName(); $obj->setName("Jerry"); say "New Name: " . $obj->getName(); say "Phone: " . $obj->getExt("phone");
|
运行结果
1 2 3
| Old name: Tom New Name: Jerry Phone: 3478-1321
|
如果想学习其他更高级的Perl面向对象编程,可以去了解一下 Mo、Moo 和 Moose等模块。
完结
🎉以上就是模块编写的一些简单总结。