[路杨Perl随笔]为什么你的Perl程序维护困难

| 2 Comments | 0 TrackBacks | WebBlog Articles

提记:最近老有人抱怨自己的Perl程序越来越难维护,也在抱怨Perl的执行效率低下,特写下自己的不成熟的体会,和同好者共勉之。

1。你的程序使用 use strictuse warnings 了吗?
不得不承认,Perl语法的随意性虽然很灵活多变,但有时间给维护和效率都带来了很大麻烦,如果碰见自己的糟糕的编程习惯和随意的语法,那么太长的代码就意味着一场噩梦,但是幸好我们有 use strictuse warnings . 有了这个,我们可以很快的找到变量的拼写错误(类似“$xxx 只使用了一次”的提醒),use strict 迫使你的语法变的严谨。当然如果你是维护别人的旧代码,而原始作者又是习惯使用 全局变量(Global symbol ) 的家伙,那么,加上 use strict 将让你陷入更大的维护危机(除非你想全部重写他的代码)。加 use strictuse warnings 困难吗? 不,你只需要在 你的程序的开头 '#!/usr/local/bin/perl' 后面加上下句就行:

use strict;
use warnings;

我的建议:
养成良好的编程习惯,尽管 Perl 语法允许你灵活和随意,新写的程序一定要加上use strict 和 use warnings .这样可以迫使你定义变量的范围,免避以后出现的效率低下和变量污染(一般都是Global symbol惹的祸 )

2。你使用模块了吗?
噢。。懒惰是 Perl 文化中的美德,难道是我们要使用现成模块而少写大量的代码的原因?我的回答是:不全是。
合理的使用Perl的标准模块或者CPAN上的成熟模块能让你的程序的后期维护变的简单,而且还可能(一般是肯定)使你的程序变的健壮和运行效率提高。
说的简单的例子,在国内的的多如牛毛的Perl在线资料(不知道经过多少次转载的东西了,叹息)中不乏有这样的 Perl CGI应用之CGI提交变量获取:

if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
} elsif ($ENV{'REQUEST_METHOD'} eq "GET") {
$buffer=$ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer); #(注1)

foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$forms{$name} = $value;
}


OK,我承认这段 code 很经典,但是有必要吗? 如果对于一个大的网站的CGI实现,每个需要处理提交参数的脚本程序都在前面加上这段话,不说其他的,就是不小心写错一个字符,也估计是维护人员的噩梦吧?不抱怨才怪。
另外,看见我标明 #(注1) 红色的代码吧?这段代码只能识别以 & 为分割的参数,而现在多数流行以 ; (分号)为分割的参数,如果要改的话,对维护人员也是个头疼的事情吧。
再分析,这段代码只能处理 key1=val1&key2=val2 这样格式的参数,如果要处理key=val1&key=val2 ( 即一个变量多个值的情况)就无能为力了:)
其实这段代码完全可以用 CGI.pm 改写,只需要以下代码:

use CGI;
$my $query =CGI->new();
my %forms = map { $_ =>$query->param($_) } $query->param(); #(注2)

就可以了,不单解决了维护人员的代码噩梦,而且可以完全处理分号隔离和一键多值问题。更可贵的,CGI.pm是Perl的标准模块(无须安装),运行效率有兴趣的朋友可以测试下,效率绝对要高的多:)

OK,关于代码维护困难的问题就简单的说这些,一家之言,只是我在学习使用Perl中的一点体会而已,请各位斧正。下次有时间,我准备和大家探讨下Perl程序效率低下的原因。



#(注2): 其实这句还是存在这安全漏洞,就好象原来的那段长代码也存在安全隐患一样,在正式的程序,还需要对获取的变量进行安全处理(比如过滤掉特殊的字符),防止产生 WebShell,让Cracker有机可乘。
办法也很简单:
my %forms = map { $_ => mysub($query->param($_)) } $query->param();

其中 mysub() 就是自定义的安全过滤函数:)
另外, 加上 my 是我的习惯,也是为了符合 use strict;,如果要彻底和上面的那一长段code等价的话,去掉这个就是了。

引用通告|TrackBacks (0)

本日志的TrackBack URL: http://easun.org/cgi-bin/mtos/tb_mt_41.pl/147.

本文相关评论|Comments (2)

对初学者的确很有用的
希望能有更多好的文章

欢迎 nsnake 来串门:)
不成熟的体会,别贻笑大方就行。呵呵。

发表该文评论|Leave a comment

最近发表|Recent Entries

[八卦]话说修路这件事

建国路貌似又在修。根本没有办法步行。这个让我想起来一个笑话:话说某A国人来北京,在东城区丢了一枚戒指,于是乎找警察,警察告诉他尽可能的帮他找。过了几天,此人发现整个东城的马路都挖开了,于是感叹曰:北京的警察真好。看来这个笑话的地点可以换在朝阳了?是不是某人的戒指又丢了?PS: 城市规划城市规划,年年挖年年修。。。生命不休,挖路不止…

[SiteLog]Blog升级到了 Movable Type Pro 4.25

Thisi is a SiteLog of Easun's WebBlog.今天终于升级到了 Movable Type Pro 4.25 ,貌似一切顺利,也没有发现什么特别大的改动?只是 Community Pack 变成了 1.62, Professional Pack 升级成了1.3 。其他的一切顺利,模版也没有修改,我甚至连重建前台HTML的事情都没有做。。。就这样吧,继续用这个风格,等有时间了再慢慢研究吧。如果非要说有什么修改的话,就是评论的登陆方式又丰富了很多,包括…

IE脚本错误,可以尝试以下办法

IE 脚本错误是个很麻烦的问题,一般定位都是 JS 引擎 和 VB 引擎出错。但是有时间反复注册 jscript.dll 和 vbscript.dll 也不能解决问题。具体表现 部分 js 解析正常,而部分就不行,尤其是基于 Web2.0的网站。不说别的,就连 ie7/ie8 本身第一次运行向导的"保存设置"也出错。其实研究下,貌似都出现在 XML 解释上? 重新注册…