perl 允许你将代码划分成一个或多个可重用的模块 1.使用关键字package 来定义模块 2.使用use和require 来加载预定义模块 3.使用"::" 记号来存取包的特定变量和子例程 包的基本知识: 关键词 package 标示着一个新的名字空间的开始,在它之后声明的所有的全局标识符 (包括变量名,子例程,文件句柄,打印格式和目录句柄)都将属于这个包(package) 例如: Vsftp:/root/perl/15# cat BankAccount.pm package BankAccount; $total = 99; sub deposit { my $amount = shift; $total += $amount; print "You now have $total dollars "; }; sub withdraw { my $amount = shift; $total -=$amount; $total=0 if $total <0; print "You now have $total dollars "; }; 1; Vsftp:/root/perl/15# cat a1.pl unshift(@INC,"/root/perl/15"); use BankAccount; my $total =10; print "$total is $total "; print "111111111111111111 "; print $BankAccount::total." "; print &BankAccount::deposit(12); print &BankAccount::withdraw(20); Vsftp:/root/perl/15# perl a1.pl $total is 10 111111111111111111 99 You now have 111 dollars 1You now have 91 dollars Perl 切换包: Vsftp:/root/perl/15# cat a2.pl unshift(@INC,"/root/perl/15"); use BankAccount; use ATM; my $total =10; print "$total is $total "; print "111111111111111111 "; package BankAccount; print $BankAccount::total." "; print "22222222222222222222 "; package ATM; print $ATM::total." "; 包与变量: 在第三章"Typeglob与符号表"中,我曾提到所有的全局名字都位于一个符号表中。 这有点像一个善意的谎言,实际上每个包都有它自己的符号表,它们之间互补相同 包与文件: 同一个包的声明可以放在多个文件中,或者多个包可以在一个文件中进行声明。 加载路径: Perl 首先在内建数组@INC 指定的路径中查找使用use或require给定的文件 Vsftp:/root/perl/15# perl -e 'print "@INC "' /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 . 包的初始化和销毁: 有时候你需要在任何代码执行前来做一些初始化工作,Perl的功能更为强大: 它允许你仍处在编译节点就有机会执行代码 Vsftp:/root/perl/15# cat a4.pl sub BEGIN { print "Washington was here "; }; for**r; Vsftp:/root/perl/15# perl a4.pl Washington was here Bareword found where operator expected at a4.pl line 4, near "**r" (Missing operator before r?) Operator or semicolon missing before *r at a4.pl line 4. Ambiguous use of * resolved as operator * at a4.pl line 4. syntax error at a4.pl line 4, near "for**" Execution of a4.pl aborted due to compilation errors. Vsftp:/root/perl/15# cat a5.pl print "11111111 "; for**r; Vsftp:/root/perl/15# perl a5.pl Bareword found where operator expected at a5.pl line 2, near "**r" (Missing operator before r?) Operator or semicolon missing before *r at a5.pl line 2. Ambiguous use of * resolved as operator * at a5.pl line 2. syntax error at a5.pl line 2, near "for**" Execution of a5.pl aborted due to compilation errors. 虽然带有语法错误得到程序一般根本就不会执行,然而位于错误之前的BEGIN 子例程还是得到了执行 私有性: Perl 中的符号是可以任意存取的,信息隐藏并不是强制的。 强制私有性: 你可以在文件范围内使用my操作符来获得绝对安全的私有变量, 因为我们和包没有任何联系,所以无法从别的域中进行存取(在这里就是指文件范围内) 符号的导入: 有时候为了省去输入的麻烦,你可能需要有选择的将一些符号导入到自己的名字空间中。 符号的导出和导入: Vsftp:/root/perl/15# cat BankAccount.pm package BankAccount; use Exporter; @ISA=qw(Exporter); ##继承Exporter @EXPORT_OK=('withdraw','deposit'); ##导出方法 sub withdraw { my $a=shift; my $b =shift; return $a + $b; }; sub deposit { my $a=shift; my $b=shift; return $a * $b; }; 1; Vsftp:/root/perl/15# cat a8.pl unshift(@INC,"/root/perl/15"); use BankAccount qw/withdraw deposit/; print &withdraw(3,4); print " "; print &deposit(3,4); print " "; Vsftp:/root/perl/15# perl a8.pl 7 12 如果模块使用@EXPORT 来代替@EXPORT_OK的话,那么用户将输出缺省的所有符号,而不管在输入列表中是否提及这些符号 我建议,作为一个模块编写人员,还是使用更礼貌的@EXPORT_OK好一些 use和Exporter 是如何工作的: 包的嵌套: 当你使用use File时,你会记得Perl 将会查找名为File.pm 的文件。 当你使用use Math::Poisson 时,Perl 将查找名位Math/Poisson.pm (Math为目录,Poisson.pm为文件) 自动加载: