perl学习之:package and module

perl的包(package)和模块(PM)

==================================包package===========================

package mypack; 包文件的其始语句

此语句定义一个名为mypack的包,从此以后定义的所有变量和sub的名字都存贮在该包关联的符号表中,直到遇到另一个package语句为止。

包文件——包是面向对象的概念

#!/usr/bin/perl

package xxx; package指令创建“类”;

sub ... 创建sub就是创建“类”的“方法”

sub ...

sub ...

1; 包文件结尾要retrun 1

包(类)引用:

&mypack'printval();在包mypack外调用包内sub
$mypack'line=10;

or

$mypack::line=10;

在包mypack外调用包内变量

perl5中建议$mypack::var

单引号引用的方式仍然支持,但将来的版本中未必支持

perl文件缺省包——main包

#!/usr/bin/perl

$i=0;

sub gotest {

}

等价#!/usr/bin/perl

package main;

$i=0;

sub gotest {

}

如果在程序里package了其它的包,当你想切换回去使用缺省的符号表,可以重新指定package main;

这样,接下来的程序就好象从没定义过包一样

包文件和模块文件都是.pm

其中模块文件,文件名必须与package 名相同

在程序里可以随时在包间来回切换

1: #!/usr/local/bin/perl

2:

3: package pack1;

4: $var = 26;

5: package pack2;

6: $var = 34;

7: package pack1;

8: print ("$var\n");

$ ./tip.pl

26

$

在Perl 5中,可以用package; 指定无当前包, 这时,所有的变量必须明确指出所属包名,否则报错

package;

$var = 21;

#error - no current package
改正
package;

$mypack::var = 21;

包造成的私有变量和方法:保证包的变量不可在其它地方使用,这样的数据即为私有数据。

1 : package privpack;

2 : $valtoprint = 46;

3 :

4 : package main;

5 : # This function is the link to the outside world.

6 : sub printval {

7 : &privpack'printval();

8 : }

9 :

10: package privpack;

11: sub printval {

12: print ("$valtoprint\n"); 只有同一个包中,才能“直接”调用此变量,其他包中调用此变量要带::前缀或切换package ...

13: }

14:

15: package main;

16: 1;

=============================================模块===============================

包package和模块module有什么不同?

创建包并将之存在同名的文件中,就是模块。

模块的创建和使用

  • 创建包文件,要求文件名为”包名.pm”(和里面的package “包名”同名)
vi file1.pm

#!/usr/local/bin/perl

package file1;

  • Require Exporter
require Exporter;

@ISA = qw(Exporter);

  • 定义@EXPORT和@EXPORT_OK
  1. sub 赋值给数组@EXPORT数组后,就能被其他文件调用,否则,在模块中定义但没有赋给数组@EXPORT的sub都是私有的,只能在模块内部调用
  1. @EXPORT_OK 定义能被其他文件调用的变量(全局变量),不在这个数组中的变量也是私有变量,则出不了模块文件。
@EXPORT = qw(readfile checkfile gotest);

# @EXPORT_OK = qw($myvar1 $myvar2);

  • 具体的sub和全局变量定义
sub readfile{

my(@tmp)=@_;

my($line);

open (MYFILE, $tmp[0]) || die ("Could not open file");

while ($line=<MYFILE>) {

print $line;

}

}

sub checkfile{

my(@tmp)=@_;

open (MYFILE, $tmp[0]) || die ("Could not open file");

my($line,$pattern,$lamp);

$pattern=$tmp[1];

$lamp=0;

while (chomp($line=<MYFILE>)) {

if($line!~/$pattern/) {

print "[$line ] :this line is wrong format\n";

$lamp=1;

}

}

if($lamp) { print "\n",$tmp[2],"\n";}

close(MYFILE);

}

sub gotest{

my(@tmp)=@_;

open (MYFILE, $tmp[0]) || die ("Could not open file");

my($line,$newline);

while ($line=<MYFILE>) {

$line=~ tr/a-zA-Z//s;

print "good \n";

print "\$line is :$line";

print "\$\& is : $&", "\n";

}

close(MYFILE);

}

  • 文件结束要return 1;
1;
  • 如何使用模块
模块文件必须先cp到perl的库目录下,才能被use
[macg@localhost perltest]$ ls testdir

file1.pl file1.pm test1

[macg@localhost perltest]$ su

Password:

[root@localhost perltest]# cp testdir/file1.pm /usr/lib/perl5/5.8.6/

[root@localhost perltest]# exit

exit

  • 在perl编程中使用模块
[macg@localhost perltest]$ vi tip.pl

#!/usr/bin/perl

use file1; use 模块

$file="/home/macg/perltest/gogo";

$pattern="\^\\d+\\.\\d+\\.\\d+\\.\\d+\$";

&readfile($file); 直接调用模块中的sub

print "-----------------------------------------\n";

$pattern="\^[0-9a-z]+[\\t ]+\\d+\\.\\d+\\.\\d+\\.\\d+\$";

$message="example:hostname1 10.10.20.2";

&checkfile($file,$pattern,$message);

[macg@localhost perltest]$ ./tip.pl

host1 202.106.0.20

host2 9.89.9.1

host3 10.0.23.6

11.0.25.9

host5 12.0.1.0as

-----------------------------------------

[11.0.25.9 ] :this line is wrong format

[host5 12.0.1.0as ] :this line is wrong format

example:hostname1 10.10.20.2

.pm文件不仅放在perl工作库目录,其实放在当前目录,也可以直接use

vi tip.pl

#!/usr/bin/perl

package main;

use file1;

[root@localhost perltest]# rm /usr/lib/perl5/5.8.6/file1.pm

rm: remove regular file `/usr/lib/perl5/5.8.6/file1.pm'? y

[macg@localhost perltest]$ ls 当前目录中

file1.pm gogo newdir newtest test testdir tip.pl

[macg@localhost perltest]$ ./tip.pl

host1 202.106.0.20

host2 9.89.9.1

host3 10.0.23.6

@INC对use命令没用,它只服务于require命令,use命令直接去访问perl模块目录(比如/usr/lib/perl5/5.8.6/)

预定义模块的导入和导出

Perl 5提供了许多有用的预定义模块,可以用use导入和no语句取消。

integer 使用整数运算

Diagnostics 输出较多的诊断信息(警告)

English 允许英文名用作系统变量的别名

Env 导入环境变量的Perl模块

POSIX POSIX标准(IEEE 1003.1)的Perl接口

Socket 装载C语言的套接字处理机制

一个导入模块和取消导入的例子:

1: #!/usr/local/bin/perl

2:

3: use integer;

4: $result = 2.4 + 2.4;

integer模块要求所有数字运算基于整数,浮点数在运算前均被转化为整数。

5: print ("$result\n");

6:

7: no integer;

8: $result = 2.4 + 2.4;

9: print ("$result\n");

$./tip.pl

4

4.8

$

Perl文档中有完整的预定义模块列表。

use 官方模块

[root@localhost perltest]# ls -F /usr/lib/perl5/5.8.6/File

Basename.pm CheckTree.pm Compare.pm Copy.pm DosGlob.pm Find.pm Path.pm Spec/ Spec.pm stat.pm Temp.pm

[root@localhost perltest]# ls -F /usr/lib/perl5/5.8.6/CGI

Apache.pm Carp.pm Cookie.pm eg/ Fast.pm Pretty.pm Push.pm Switch.pm Util.pm

#!/usr/bin/perl

chomp($file=<>);

chomp($file2=<>);

&gotest($file,$file2);

sub gotest{

my(@tmp)=@_;

use File::Copy; File::Copy即/usr/lib/perl5/5.8.6/File/Copy.pm

copy($tmp[0], $tmp[1]);

}

[macg@localhost perltest]$ ./tip.pl

test

newtest

[macg@localhost perltest]$ ls

newtest test testdir tip.pl

perldoc 查询官方模块的用法

  • 先确定perl5的lib根目录
[macg@localhost perltest]$ ls /usr/lib/perl5/5.8.6

abbrev.pl bigrat.pm DB.pm Fatal.pm I18N NEXT shellwords.pl Thread.pm

AnyDBM_File.pm blib.pm Devel fields.pm i386-linux-thread-multi NEXT.pm sigtrap.pm Tie

assert.pl bytes_heavy.pl diagnostics.pm File if.pm open2.pl sort.pm Time

Attribute bytes.pm Digest file1.pm importenv.pl open3.pl

  • 再确定感兴趣的模块
[macg@localhost perltest]$ ls /usr/lib/perl5/5.8.6/Net

Changes.libnet Config.eg demos FTP hostent.pm libnet.cfg netent.pm NNTP.pm Ping.pm protoent.pm servent.pm Time.pm

Cmd.pm Config.pm Domain.pm FTP.pm Hostname.eg libnetFAQ.pod Netrc.pm Ping POP3.pm README.libnet SMTP.pm

  • perldoc查询用法
[macg@localhost perltest]$ perldoc Net::FTP

基于perl lib根目录

NAME

Net::FTP - FTP Client class

SYNOPSIS

use Net::FTP;

$ftp = Net::FTP->new("some.host.name", Debug => 0)

or die "Cannot connect to some.host.name: $@";

$ftp->login("anonymous",鈥?anonymous@鈥?

or die "Cannot login ", $ftp->message;

$ftp->get("that.file")

or die "get failed ", $ftp->message;

$ftp->quit;

CPAN (Comprehensive Perl Archive Network)

安裝CPAN的module

下载DBI-1.37.tar.gz
安装
tar xvzf DBI-1.37.tar.gz

cd DBI-1.37

perl Makefile.PL

make

make test

make install

使用module
#! /usr/bin/perl

use DBI; # 宣告使用 DBI module內的所有"方法"

my $db="test";

my $host='localhost';

my $user='root';

my $password='ppp123';