Perl无废话入门指南
最近接到一个任务是这样的,一台
Solaris
服务器上需要运行一个脚本,每天统计
MySQL
数据库中的数据并生成报表。本来这是一个可以就事论事的小项目,但是为了以后的灵活和可扩展性,我设计了一个使用
XML
做统计模版配置的方案。由于在
Bash
下不太好实现
XML
的访问,因此我考虑用
Perl
来实现这个脚本。
Perl
是一个强大的脚本语言,本来是设计应用在文本处理方面的,但是后来发展的越来越强大,已经可以处理网络、图形、系统、文件等等各个方面的内容。
Perl
本身内置了丰富的操作符和函数,外部也有多年积累下来的大量模块。但是不知道什么原因在国内好像很少有人用。关于
Perl
的历史我就不多说了,有兴趣可以上网查一下。有一点要说的是,目前
Perl
最新的版本是
5.8.6
,而
Perl6
虽然已经设计很久了但是由于自举问题目前还没有一个可用的版本。为了解决这个问题,台湾的唐宗汉发起的
Pugs
项目正在快速的实施中,可能很快就能有结果了,有兴趣的朋友可以多多关注一下,也许还可以为开源世界做点贡献。
虽然很早以前就了解过
Perl
,但是从来就没有实际的用它做过项目,因此这次的实现是一个边学边做的过程。作为一个程序员,学习一种新的语言总会有一点惯性思维,加之
Perl
在语法上与
C
语言比较类似。因此我想在这片文章中主要以
C
为背景做一个比较。这种比较不是比较语言上的优劣,而是说明同样的功能如何在
Perl
中实现以及之间的区别。限于篇幅,具体的技术实现的细节我就不在这里多说了,你可以在末尾的资源一节中找到很多相关的文章。如果你没有接触过
Perl
,我想你可能更希望看到学习
Perl
的过程中可能会遇到的一些问题以及解决方法。
工欲善其事,必先利其器
要写代码,首先至少得有一个编辑器。
Perl
是跨平台的一种解释型语言,可以在
Unix/Linux/Windows/Mac
等平台上运行。具体对应平台上的编辑器,最简单的方案是
Unix
下用
vi
,
Windows
下用
UltraEdit
。当然也有商业化的
IDE
,不过我尝试了一下发现并不是那么的好用,因此我在
Windows
平台上以
UltraEdit
作为编辑环境,完成后移植到
Solaris
平台上。
关于环境的搭建,有这样几个需要注意的地方:
1、
Windows
平台下对应的是
ActivePerl
,可以免费下载。
2、
去
UE
的网站上下载
Perl
的
AutoComp
文件,可以实现自动完成功能。
3、
下载
Perl
对应的语法加亮的
Tag
文件并加入到
UE
中,可以更块的发现拼写错误。
4、
在
UE
设置一个快捷工具,命令行为
C:\Perl\bin\perl.exe "%F"
(捕获输出),可以实现快速运行并显示结果。
5、
如果你不喜欢
UE
,那么我推荐
Source Insight
巧妇难为无米之炊
起始从某种角度来说,程序员和厨子是一样的。要做出一桌大餐来,首先得看看手上有什么原料,然后才能琢磨一下用这些东西能做出什么好吃的来。或者说想做什么东西,得先备好料才行。
看看我们现在都有什么:一个编辑器,一个
Perl
的开发环境,还有一个聪明的脑袋。这个任务中,我要处理命令行参数、访问
MySQL
数据库
(SQL)
、读写
XML
的配置文件以及输出一个固定格式的报表文件。
好了,去查查资料,看看访问数据库和读写
XML
都需要什么东西。正如同
C
语言本身带了很多标准函数库一样,
Perl
本身也有函数库,并把这些函数库称为
Module
(模块)。查了一下资料,发现要访问
MySQL
数据库需要
DBI
和
DBD::MySQL
两个模块,那么去哪里找这些模块呢。这里给大家介绍一个
Perl
的
Module
集散地
www.cpan.org
,这里包含了八千多个
Module
,可以从这里下载到几乎各种各样的
Module
。可以手工下载后安装,也可以使用工具来自动安装。在
Windows
下是可以使用
ppm
进行自动安装,例如
DBD
的安装过程如下:
C:\>ppm
ppm> search DBI
Searching in Active Repositories
…
一大堆与
DBI
相关的包的列表,其中就包括
DBI
这个包
ppm>install DBI
ppm>install DBD::mysql
如果知道模块的名字也可以直接安装
ppm>quit
如此就安装完成了。附带说一下,
Linux
下没有
ppm
,但是有类似的方式。输入命令行
perl –MCPAN –e shell
然后
install DBI; install DBD-mysql
,和上面的操作几乎是一样的。
提示:如果是在
linux
下安装
DBD::Mysql
模块,需要把
mysql
的
bin
目录包含在环境变量
PATH
中,否则会提示找不到
mysql_config
文件。
mysql
一般是安装在
/usr/local/mysql
下,因此可以通过执行命令行
PATH=$PATH:/usr/local/bin/mysql/bin
来将此路径加入到环境变量中。
访问
XML
有几种包可以选择:使用
DOM
和
Simple
模块。
Simple
模块是把
XML
用
Perl
的数组方式表示,而
DOM
是
W3C
维护的一个基于树的
XML
文档标准。具体用哪种就看个人的需要了。我使用的是
DOM
,因此要安装
XML-DOM
包,方法同上。
说起编程语言,简单的来说无非就是这样几个必不可少的基本元素:变量、数据、表达式、流程控制语句(包括条件、分支、循环
)
、函数、对象。具体到语言上,大部分的内容只是表达的形式不同而已。而
Perl
与
C
又有什么区别呢?
首先要知道,
Perl
是一种脚本语言。所谓的脚本,就是没有主函数,从最开始一行一行的按照顺序解释执行(老版
Basic
不也是如此吗)。因此,尽管把你的思路转化为流程用
Perl
表达出来吧。
其次,
Perl
的设计中参考了很多语言的长处,并避免了设计上的缺陷。因此
Perl
的很多语法你可能都会觉得似曾相识。我把
Perl
的语法总结了一下,和
C
语言做了一个简单的对比表格。表格左右两边的语句是
C
和
Perl
对应表达同一个功能各自的不同方式。如果读者有C语言的经验,相信看到这个对比可以很快的上手吧?
if
结构可以反转,意义不变,注意前句没有分号。
顾名思义
, unless
是“除非”的意思。这里的四个表达方式是等价的。注意第一种方式中,条件部分的圆括号和语句部分的花括号是不可省略的。
foreach (@arry)
foreach my $key(@ary)
foreach $count (1..10)
for/while
的语法都和
C
类似。
foreach
关键字也可以用
for
,意义不变。
int max(int x, int y)
return x>y?x:y;
int n=max(1,2);
sub max
my ($x, $y)=@_;
return $x>$y?$x:$y;
my $n=max(1,2)
注意下划线
”_”
也是一个合法的变量名。而
@_
是
Perl
内置的一个数组,内容为函数的参数。
my ($x, $y)
表示声明了一个有两个元素的数组,并将两个元素映射到
$x
和
$y
上。
($x,$y)=@_;
则表示两个数组之间的复制,
@_
中对应的元素的值就赋值给了
$x
和
$y.
这是一个简便的写法,也可以这样写
my $x=$_[0]; my $y=$_[1];
return
是可选的,默认返回最后一个表达式的值
1.
编译时打开编译器所有的警告选项
2.
使用
lint
工具
3.
perl –w myprogram.pl
打开运行警告开关,如果运行时
Perl
检查到了可能的错误,会显示警告信息,否则它默认是什么也不提示继续执行。
4.
#!/usr/bin/perl –w
在代码文件第一行中加入
-w
选项开关
5.
use strict;
使用严格语法约束
编译后直接执行
1.
perl myprogram.pl
手工执行
2.
#!/usr/bin/perl
Unix
下在代码第一行加入,然后给文件加上可执行的属性
chmod +x myprogram.pl
,之后就可以用
./myprogram.pl
命令来运行。
3.
Windows
下,安装
ActivePerl
的时候,已经将
.pl
后缀的文件和
perl
的解释程序关联起来了,因此直接双击文件图标就可以运行。
需要说明的是,在
Perl
的世界中有一句名言“条条大路通罗马”,
这句话的意思是说同样一件事情
Perl
允许你用很多种不同的方式去做。因此上表的例子风格是按照
C
的习惯来写的,并且为了简化起见,只是挑选了与
C
相似的内容。事实上,
Perl
包含了很多
C
没有的东西,例如内置的
Hash
表、队列、正则表达式、格式定义等等。
从框架开始
Perl
有很多表达方式,我们可以选择一种自己熟悉、容易理解的方式来写
Perl
的程序。例如,你是一个经验丰富的
C
程序员,那么你可以选择以
C
的风格来写
Perl
程序。下面是一个小小的样板框架
#!/usr/bin/perl -w
use strict;
#
程序开始的第一行语句,调用
main
函数
main();
#
定义
main
函数
sub main
在这个框架下面,你几乎可以容易就开始你的
Perl
开发了。如果需要处理命令行参数,就可以稍微的扩展一下这个框架。
#!/usr/bin/perl -w
use strict;
use Getopt::Std;
main();
my $configfile;
sub ProcessOptions
my $VERSION = '
1.0.0
';
my $USAGE = "pp.pl [-v | -c configfile]\n";
my $opts={};
die $USAGE unless( getopts("c:v", $opts) );
die $VERSION if ($opts->{'v'});
$configfile=$opts->{'c'} ? $opts->{'c'} : 'config.xml' ;
sub main
ProcessOptions();
print $configfile;
实际上,剩余的工作和以往的工作差不多了,编写一个一个的函数,并实现你的业务逻辑。对于你这样一个聪明的程序员来说,学会
Perl
是一个很容易的事情。
以我的学习经验来看,在开发的过程中可能有一些常用但是很分散的细节问题会让你感到困惑。
1、
程序的入口参数怎么取?
内置数组
@ARGV
包含了所有的运行参数。可以打印出来看看
print @ARGV;
2、
函数如何传参数、取参数?
每个函数内部都有一个内置的数组
@_
,这个数组的元素就是函数的参数。例如传入的第一个参数就是
$_[0]
,第二个是
$_[1]
。唔,如你所见,
Perl
的函数参数就是
C
中的动态参数。
3、
默认变量是什么
这个可能会把你的头搞晕。有一个内置变量
$_
,
4、
显示消息、退出常见的简单写法
die ‘Error on program’;
也可以在条件不满足的情况下使用
die ‘Configuration error’ unless($doc->getDocumentElement);
5、
格式化输出
可以用简单的
print
语句进行一般的输出操作,如果需要复杂的格式化输出,可以使用
printf
语句……跟
C
的用法几乎是一样的。
printf("pi=%
.6f
", 355/113);
6、
=>
是什么东西
?
在使用
Hash
表的时候,可以经常看到
=>
这个符号。例如这样的一个定义
:
my $account={
'Simon'=> 'simon@email.com',
'
Jesse
'=> 'jesse@email.com'
其实,
=>
符号跟逗号
”,”
是等价的。
Perl
里面的
Hash
表事实上是一个数组,只是把奇数位元素看做是
Key
(键),而把偶数位的元素看做是
Value
(值)。
7、
关于引用的一点说明
Perl
的引用类似
C
的指针,所谓的引用事实上就是地址。取一个变量的地址用反斜杠
”\”
操作符,例如
$p=\$x;
那么
$p
就是一个指向
$x
变量的指针。要引用指针的值,使用
”$”
操作符,例如
print $$p;
就是打印
$x
的值。
引用不单单可以引用变量,也可以引用数组、
HASH
表、函数,取函数的地址可以使用
*
操作符。
还能做什么
Perl
作为一个功能强大的脚本语言,可以应用在
Web
编程、数据库、
XML
、系统管理、图形图像、自然语言、压缩、加密、邮件系统、软件测试等各个地方。在
CPAN
上,你可以找到各种各样你所需要的模块支持。例如,你可以:
l
编写系统管理的脚本
l
和
Apache
结合起来,编写
CGI
程序
l
编写动态网页
l
使用
Net
命名空间下的类编写网络应用程序
l
使用
Authen::Captcha
模块实现提交时的验证码的功能
l
使用
Storable
模块处理
Perl
的各种数据结构
l
使用
GD/Image::MagicK
模块处理图形
l
等等
…
www.perl.org
Perl
的官方站点
www.perl.com
O’Reily
维护的关于
Perl
的站点
www.cpan.org
Perl
的
Module
资源大全
www.perlchina.com
中国
Perl
协会
www.pm.org
世界各地的
Perl
用户组织
www.perlmonks.org
用
Perl
写诗
J
http://www-128.ibm.com/developerworks/cn/linux/sdk/perl/
IBM
社区的
Perl
系列文章