包的基本知识:
关键词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它的程序输出这些名字(也只有这些名字).
而且它还应在用户未指定名字列表时有相应的对策。