包的基本知识:

关键词package 标志这一个新的名字空间的开始,在它之后声明的所有的全局标示符

(包括变量名,子例程,文件句柄,打印格式和目录句柄)都将属于这个包(package),例如:


perl 包编写:


zjzc01:/root/perl# cat t15.pl
package BankAccount;
$total =0;
sub deposit{
my ($amount)=@_;
$total += $amount;
print "You now have $total dollars\n";
}

sub withdraw{
my ($amount) = @_;
$total -=$amount;
#$total=0;if $total<0;
print "You now have $total dollars\n";
}
1;

zjzc01:/root/perl# cat t16.pl
require "t15.pl";
BankAccount::deposit(10);


zjzc01:/root/perl# perl t16.pl
You now have 10 dollars

用户定义的全局标示符$total,deposit和withdraw 属于包BankAccount,



包的作用域一直延伸到最内层的封闭代码块的结束(如果它在那个代码块中定义的话)


或持续到另一个package语句的开始。


下面是你如何使用另一个包中的全局符号的例子:

package ATM; ##开始一个新的名字空间

BankAccount::deposit(10) ###调用一个外部子例程


zjzc01:/root/perl# cat p1.pl
package A;
$a=10;
1;
zjzc01:/root/perl# cat p2.pl
package B;
$a=20;
1;
zjzc01:/root/perl#
zjzc01:/root/perl# cat p3.pl
require "p1.pl";
require "p2.pl";
package A;
print "\$a is $a\n";
package B;
print "\$a is $a\n";
zjzc01:/root/perl# perl p3.pl
$a is 10
$a is 20



包与变量:

在第三章"Typelob与符号表",我曾提到所有的全局名字都位于一个符号表中。

这有点像一个善意的谎言。实际上每个包都有它自己的符号表,一节中更多的谈到这个问题。)


在包main中定义的标识符并不会被特别对待。除了有一点例外,那就是你还可以以另一种形式

"$::x:"来指定那个包中的变量$x.


那些诸如$|,$_,@ARGV和%ENV之类的内建变量总是属于包main的,而且Perl允许你在其他包重直接使用它们,


而无须加上前缀main:: 这些是Perl中唯一真正的全局变量。


包与文件:

同一个包的声明可以放在多个文件中,或者多个包可以在一个文件中进行声明。


加载路径:

zjzc01:/root/perl# perl -e 'print "@INC\n";'
/usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .


在调用require 之前更改@INC;


unshift (@INC,"/use/perl/include");
require 'foo.pl';


符号的导入:

有时为了省去输入的麻烦,你可能需要有选择的将一些符号导入到自己的名字空间中。


例如, 你想以sqrt来代替math::sqrt 或者以deposit 代替

BankAccount::deposit .use 语句可以让你指定一组可选的用来导入的函数名:


use BankAccount('withdraw','deposit');

withdraw(); ###现在你无须使用全能限度就能调用它了


就模块来说,它必须已经准备好向任何use它的程序输出这些名字(也只有这些名字).

而且它还应在用户未指定名字列表时有相应的对策。