﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-如鱼饮水-文章分类-Perl编程技巧</title><link>http://www.cnitblog.com/ttyuren/category/5376.html</link><description>perl学习记录</description><language>zh-cn</language><lastBuildDate>Thu, 06 Oct 2011 04:58:37 GMT</lastBuildDate><pubDate>Thu, 06 Oct 2011 04:58:37 GMT</pubDate><ttl>60</ttl><item><title>Perl小技巧：文件操作</title><link>http://www.cnitblog.com/ttyuren/articles/27188.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:16:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27188.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27188.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27188.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27188.html</trackback:ping><description><![CDATA[<h1>Perl小技巧：文件操作</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/SaladJonk/"><u><font color=#0000ff>SaladJonk</font></u></a><br>出处：<a href="http://www.perlchina.org/"><u><font color=#810081>中国Perl协会</font></u></a> <a href="http://fund.perlchina.org/"><u><font color=#0000ff>FPC</font></u></a>(Foundation of Perlchina)<br>翻 译：SaladJonk <br>审 校：qiang <br>出 处：中国Perl协会 FPC(Foundation of Perlchina) <br>原 名：Perl circus:file operation <br>作 者：Luke Melia <br>发 表：2002 <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：50分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=31#文评"><u><font color=#0000ff>[查看文评]</font></u></a></p>
            <u><font color=#0000ff>
            <hr>
            </font></u></td>
        </tr>
    </tbody>
</table>
<p><u><font color=#0000ff></font></u></p>
*找到具有指定特征的文件*
<pre>$path = "/path/to/dir/";
opendir DIR, $path;
@arr1 = readdir DIR;
@arr2 = grep{-T "$path$_"} @arr1; #text files only
@arr3 = grep{!-d "$path$_"} @arr1; #no directories
@arr4 = grep{-s "$path$_" &lt; 1024} @arr1; #less than 1K
</pre>
代码解释：假如被测试的目录项是一个文本文件，那么 -T 文件操作符就会返回真。其实针对目录项的测试操作还有很多。（注：文件和目录在系统中都是以目录项的形式来管理的，所以要区别一个目录项指向的是一个文件还是一个目录需要相应的操作符）。注意上面的 readdir 函数返回指定目录下的所有目录项。因为在 grep 函数中对目录项的测试需要文件的完全路径，所以我们把 $PATH（存储了目录项的部分路径） 和 $_（存储了目录项的名字）中的内容联合起来得到文件的完全路径 *对目录进行递归搜索*
<pre>use File::Find;
find(\&amp;handleFind, 'imac:documents:code');
sub handleFind{
my $foundFile = $File::Find::name;
print "$foundFile\n" if ($foundFile =~ /\.html?$/i);
}
</pre>
RESULT: imac:documents:code:index.html imac:documents:code:perl:example.HTM 运行结果： 代码讨论：那些工作于 Unix 系统的 Perl 程序员可以非常简便的利用 UNIX 上提供的工具来完成许多日常的工作，比如递归的列出指定目录下的所有目录项（也就是列出指定目录及指定目录子目录下的所有目录项目）。然而 Perl 的一个最大的特征就是可以运行于很多的平台上。所以如果你碰巧工作在一个非 UNIX 的平台，或者如果你虽工作在 UNIX 平台，但不喜欢使用系统工具写脚本，你可以选择 Perl。要完成这些巧妙的工作，你需要使用 perl 中的 File:Find 模块。当你加载了这个模块的时候，你就可以使用其中的 find 子函数，在调用这个函数的时候，需要带参数：第一个参数是一个函数的引用，这个函数由你自己建立，每次一个文件被找到的时候，它都会运行。接下来的一个参数是一串你想要搜索的路径。我写的这个示例脚本是运行在 Macintosh OS 8.x 系统上的，所以我使用了 Mac 系统的路径分隔符 ：。如果是在 Windows，你可以用反斜杠，如果是在 Unix 系统则是正斜杠（至于在 Amiga 系统上用什么我就不知道了）。总之，find 函数将会在每次找到一个文件的时候调用你给出的子函数，而且会对子目录进行查找。在我的 handledfind 子函数中，我通过这个模块特定变量 $File::Find::name 来获得每次 find 找到的文件名。然后，就可以对该文件执行任何你想的测试，在上面的例子中，我们输出有 .html 的扩展名文件名。 *文件读操作* *一次读入整个文件内容。*
<pre>open FH, "&lt; anthem";
$/ = undef;
$slurp = <fh>;
print $slurp;
</pre>
运行结果：一下就显示了所有的文件内容，此刻你应该非常的自豪。:) 代码讨论：尖括号 &lt;&gt; 对文件句柄进行操作，在标量上下文中它将返回文件的下一条记录，在数组上下文中它将返回所有的记录。在默认的情况下，文件中的记录被认为是由换行符分开（例如回车或其他代表新行开始的字符）。你可以重新设定这个默认的分隔符，然后 Perl 将会以你指定的分隔符为准来替代换行符。全局变量 $/ 里存储了输入文件的分隔符，如果你把 $/ 的值设置为 undef ，那么 Perl 将会认为整个文件是一条记录（因为此刻已经没有文件分隔符了）。牢记 $/ 是全局变量，千万不要在脚本的其他地方不经意的改变它，这个错误将很难被发现。你可能会问，我们能否不改变 $/，而采用把文件的所有记录读到一个数组中，然后把数组联合成一个很长的字符串（比如 $slurp = join("",<fh>);)的方法实现一次读入文件。当然这也是一个有效的解决办法，但是你会发现它很慢，是否选用它取决你的应用，取决于你是否关心运行速度。 *赋值* *把一个文件句柄赋给另一个文件句柄*
<pre>open(MYOUT, "&gt; bottle.txt");
*STDOUT = *MYOUT;
print "message";
</pre>
运行结果：文本文件 bottle.txt 现在包含 message 字符串。代码讨论：以前可能你配合使用过 Print 函数和文件句柄，但是你是否知道就算你没有使用文件句柄，Perl 也默认你在使用一个称为 STDOUT 的句柄？C 程序员知道 STDOUT 代表标准输出，也就是通常的屏幕，或终端窗口（或者是 CGI 程序的输出端 － 浏览器）。在这里我们完成的工作是创建我们自己的文件句柄，它指向一个给定的文件，然后我们做了一件比较鬼的工作，使用 * 前缀把 STDOUT 转换为 typeglob 类型。Typeglob 类型的数据可以有别名，这样一个变量可能会指向另一个其他名字的变量。上面第二行代码使 STDOUT 指向 MYOUT 变量。所以执行 print 操作时的默认输出对象也就成为了我们创建的文件句柄。 *同时向两个文件句柄执行写操作*
<pre>use IO::Tee;
$tee = IO::Tee-&gt;new("&gt;&gt; debuglog.txt", \*STDOUT);
print $tee "an error ocurred on ".scalar(localtime)."\n";
</pre>
运行结果：an error ocurred on Fri Feb 23 21:44:20 2001 代码讨论：如果，由于种种原因你想要同时向两个位置写入同一个字符串，这和 UNIX 下的 tee 工具的用途一样。即使你不是工作在 Unix 平台上，Perl 也通过 Tee 模块为你提供这个功能。Tee 模块可以在 CPAN 下载，你应该把它安装到 Perl 的 IO 库文件夹中。Tee 模块以 OOP 方式编写，所以使用它之前你应该首先使用它的 new 方法来创建一个 Tee 对象，整个过程需要两个参数，每个参数既可以是代表文件句柄的字符串，也可以是一个对已打开的文件句柄的引用。在上面的例子中，我们用一个字符串来代表一个以附加模式打开的文件句柄，它指向名为 debuglog.txt 的文件，另一个参数是系统内置的文件句柄 STDOUT，整个句柄是系统自动创建的，print 函数默认情况对它进行操作。为了得到一个文件句柄的引用我们需要对一个 typeglob 类型的数据使用反斜杠。Typeglob 可以代表任何已命名的某个变量，不论它是数组，散列还是标量等。使用 * 很有必要，因为文件句柄自己没有前缀符号。new 操作符返回 Tee 类的一个实例对象，然后我们把整个实例赋给 $tee 标量。现在，无论什么时候我们向 $tee 进行写入操作，我们都同时向两个位置进行写操作。 *更多文件操作。。。* *从一个文件的完全路径中找出它的名字*
<pre>use File::Basename;
$path = "/docs/sitecircus.com/html/tricks/trick.of.the.week.html";
$basename = basename($path, ".html");
print $basename;
</pre>
运行结果：trick.of.the.week 代码讨论：好了，成功了。问题是要找出文件的名字，要不带任何路径前缀，不带任何扩展名。File::Basename 模块可以使这很容易实现，我们只需要把文件的完全路径还有要剔除的扩展名传给它。上面的 path 变量是文件的完全路径，注意文件分隔符是 /，这个字符很特殊，因为它是操作系统的保留字符。这里你不能在文件名里使用系统的分隔符。你应该知道当今流行的操作系统都使用自己独特的文件分隔符：Unix使用 /，Windows 使用 \，Macintosh 使用 :（顺便说一下，在 Windows 上的 Perl 脚本中，你既可以使用 \也可以使用 /作为文件分隔符，Perl 的解释器能理解你的意思)。File::Basename，当然，能正确在完全路径中找到文件名，不论时在什么系统下。 *改变文件的所有者*
<pre>($uid, $gid) = (getpwnam($username))[2,3]
or die "$user not in passwd file";
chown ($uid, $gid, $file)
or warn "couldn't chown $file.";
</pre>
运行结果：无输出代码讨论：有的时候，你可能知道一个用户名，而你想用这个用户名做些事，比如改变一个文件的所有者。但是不幸的是，Perl 的 chown 命令不能接受用户名作为参数，但是可以接受一对数字:userid 和 groupid。虽然有这些不便之处，Perl 并没有让我们陷入困境，我们可以把用户名作为 getpwnam 函数的参数，获得一个数组，里面包含了用户名对应的 userid 和 groupid，分别对应着数组里的第二和第三个元素。 
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:16 <a href="http://www.cnitblog.com/ttyuren/articles/27188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Perl学习指南</title><link>http://www.cnitblog.com/ttyuren/articles/27187.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:15:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27187.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27187.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27187.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27187.html</trackback:ping><description><![CDATA[<div class=topbanner><img src="http://www.perlchina.org/images/logo/perlchina_org.gif"> </div>
<div id=Content>
<h1>Perl学习指南</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/qiang/">qiang</a><br>出处：<a href="http://www.perlchina.org/">中国Perl协会</a> <a href="http://fund.perlchina.org/">FPC</a>(Foundation of Perlchina)<br>原 名：Perl学习指南 <br>作 者：qiang <br>审 校：JackyCheng <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：164分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=46#文评">[查看文评]</a></p>
            <hr>
            </td>
        </tr>
    </tbody>
</table>
<p>&#160;</p>
<div id=Container style="WIDTH: 600px">
<div id=Content style="WIDTH: 600px">
<div id=revision>首先，来到 Perlchina 就是找对学习 Perl 的第一步。
<h3>每个人都有不同的学习方法, 下面列举几个供参考:</h3>
<p>首先,请考虑如下问题:</p>
<ul>
    <li>如果 Perl 是你学的第一个编程语言，推荐先看一些编程基础，流程控制,逻辑和设计的知识. <em>大家有没有好的中文书籍介绍？</em>
    <li>如果你学过其他语言，那就可以从学习 Perl 的语法开始（<a href="http://www.oreilly.com.cn/book.php?bn=7-5083-1113-2">Perl语言入门</a><br>），或者是从 Perl 的自带文档。当你对 Perl 的语法了解后，尝试书中的例子，试着写一些简单的程序。很快你就会发现 Perl 和你以前学过的语言类似。
    <li>如果你是一个有经验的程序员，你可能直接会从读程序，尝试理解开始。虽然不同语言有很多相像之处,但很多时候你还是会迷惑的。推荐至少先了解 Perl 的基本语法。
    <li>一个几乎通用的方法是，首先学习文档或书籍，尝试其中的程序例子，试着改动，然后修改出错的地方。然后再接着读，尝试复杂些的程序，重复以上的步骤。阅读+实践是最好的学习方法。 </li>
</ul>
<p>同时，你还需要这样:</p>
<ul>
    <li>给自己设一个学习目标，为什么学习 Perl，用 Perl 来做什么。知识是在实践中学到的。试着用 Perl 来写一个留言本，家庭影集，分析日志程序等。不要一上来就打算写一个网络商店的复杂程序，从小的程序开始更容易看到学习的进展，激励自己学习下去。
    <li>闭门自学的人往往要花更大的力气学习，而且往往会多走弯路。如果学习 Perl 的时候可以参与到 Perl 的社区里，那么你就可以和其他 Perl 的用户交流经验，获得帮助。如果英文好的话，你可以访问 <a href="http://perlmonks.org/">perlmonks.org</a> 等网站，聚有很多 Perl 的高手。 </li>
</ul>
<h3>学习窍门:</h3>
<ul>
    <li><strong><font color=#000000>查询文档</font></strong><br>如果你对某个函数的使用不清楚，那么在命令行上使用 <code>perldoc 函数名</code> 来查阅 Perl 自带文档。你也可以把 <code>函数名</code> 替换为模块名来查阅模块文档。例如 <code>perldoc LWP::Simple</code> 当然, 如果英文有困难的话，还是建议阅读 Oreilly 书籍。
    <li><strong><font color=#000000>程序调试</font></strong><br>不管你的程序多短，使用 use warnings 和 use strict 对你找到错误有非常大的帮助。庆幸的是, <a class=existingWikiWord href="http://wiki.perlchina.org/main/show/klaus">klaus</a> 已经翻译了一篇绝妙的调试文章 <a href="http://wiki.perlchina.org/main/show/brian's%20Guide%20to%20Solving%20Any%20Perl%20Problem">Brian 的 Perl 问题之万能指南</a>
    <li><strong><font color=#000000>提问的智慧和寻找答案的能力</font></strong><br>初学时碰到的许多问题都已经被别人问过了而且很有可能已经被回答了。所以，你要学会使用 google 或论坛搜索你的答案。遇到问题时，你可以把问题表达出来，阅读相关文档，尝试写程序自己解决。如果实在没有头绪的话，最后尝试到论坛里或者是用户组来提问，通常，大家更乐意帮助那些已经对自己的问题作过研究的人，那些只要答案的人常常没人理睬。学习语言是一个自己反复研究，尝试的过程，不要依靠别人的帮助。<br>有时间你可以看看 <a href="http://www.linuxforum.net/doc/smartq-grand.html">提问的智慧</a> 帮助你更快得到别人的帮助。 </li>
</ul>
<p><a class=existingWikiWord href="http://wiki.perlchina.org/main/show/JackyCheng">JackyCheng</a> 的见解 (摘自 PerlChina 论坛 <a href="http://xrl.us/fz9e">http://xrl.us/fz9e</a> )</p>
<ul>
    <li>个人认为学习Perl是一件终身的事情，入门的话，先把Perl基本语法、操作符、函数、控制流程等任何语言都有的基础弄清楚，然后入门后，在根据自己的需要继续发展。
    <li>Perl是一个大杂烩语言，分支很多，所以我建议你先明确你要用Perl做什么。如果只是简单的想学perl，并没有具体目的，那么入门的时候不易过分综合，有些不实用的东西，了解即可。
    <li>学习Perl最重要的事情是实践，很多东西即使顶尖的高手也是无法解决的，所以需要勤于亲身实践。个人认为你应该先去了解一下perl的文化，这样能够多增加一些对于perl的爱好。
    <li>另外，perl有句名言叫做&#8220;条条大路通罗马&#8221;，记住任何事情不止一种方法解决，选择最适合你的，祝你成功。 </li>
</ul>
<h3>Perl 学习资源</h3>
<h2><strong><span style="FONT-SIZE: 11pt">初学者推荐书籍</span></strong></h2>
<p>请只使用大家公认的 Perl 书籍。漏洞百出的书只会把你带入歧途。大部分人都会推荐 Oreilly 出版的 <a href="http://www.oreilly.com.cn/indexcat.php?c=perl">Perl 丛书</a></p>
<ul>
    <li><a href="http://www.oreilly.com.cn/book.php?bn=7-5083-1113-2">Perl语言入门（第三版）</a><br>又叫小骆驼。初学者使用。
    <li><a href="http://oreilly.com.cn/book.php?bn=7-5083-0512-4">高级Perl编程</a><br>又叫黑豹书，应该算是learn perl的升级版，如果想成为perl黑客或者高手的话，不可不读。
    <li><a title="programming perl" href="http://oreilly.com.cn/book.php?bn=7-5083-0730-5">Perl语言编程（第三版）</a><br>又叫大骆驼。囊括了 Perl 的所有知识，适用于查阅和检索，和 perl 附带的英文手册有一拚。
    <li><a title=第二版 href="http://oreilly.com.cn/book.php?bn=7-5083-0624-4">CGI编程－使用Perl</a><br>关于使用 Perl 来编写 <span class=caps>CGI </span>程序。 </li>
</ul>
<h2><strong><span style="FONT-SIZE: 11pt">推荐在线学习资源</span></strong></h2>
<ul>
    <li>英文资源
    <ul>
        <li><a href="http://perlmonks.org/index.pl?node=Tutorials">perlmonks 教程</a>
        <li><a href="http://users.easystreet.com/ovid/cgi_course/">CGI 教程</a>
        <li><a href="http://www.stonehenge.com/merlyn/columns.html">Randal L. Schwartz 的 Perl 专栏</a>
        <li><a href="http://www.perl.com/pub/q/Article_Archive">perl.com 文章</a>
        <li><a href="http://pleac.sourceforge.net/pleac_perl/index.html">Perl 用法,窍门收集</a><br>　 </li>
    </ul>
    <li>中文资源
    <ul>
        <li><a href="http://perl.hcchien.org/TOC.html">Perl 学习手札 繁体版</a>
        <li><a href="http://mailport.91i.net/perl.htm">Perl 学习手札 简体版</a>
        <li><a href="http://www.flamephoenix.net/perl/index.htm">Flamephoenix 的Perl教程</a> </li>
    </ul>
    </li>
</ul>
<h2><strong><span style="FONT-SIZE: 11pt">英文文档资源</span></strong></h2>
<ul>
    <li><a href="http://perldoc.perldrunks.org/">在线 perldoc 文档镜像 1</a>
    <li><a href="http://www.perldoc.com/">在线 perldoc 文档镜像 2</a>
    <li>如果你在 C 盘下装有activeperl，可以参考自带的本地文档file:///C:/Perl/html/index.html </li>
</ul>
<h2><strong><span style="FONT-SIZE: 11pt">CPAN 资源</span></strong></h2>
<ul>
    <li><a href="http://search.cpan.org/">CPAN 模块搜索主站</a>
    <li><a href="http://cpansearch.perl.org/">CPAN 镜像</a>
    <li><a href="http://kobesearch.cpan.org/">CPAN 模块搜索</a> </li>
</ul>
<h2><strong><span style="FONT-SIZE: 11pt">CPAN 国内镜像</span></strong></h2>
<ul>
    <li><a href="http://cpan.linuxforum.net/">linuxforum</a>
    <li><a href="ftp://mirrors.hknet.com/CPAN/">香港镜像</a>
    <li><a href="http://mirrors.dayouit.com/CPAN/">广州镜像</a> </li>
</ul>
<h2><strong><span style="FONT-SIZE: 11pt">activeperl ppm 资源</span></strong></h2>
<ul>
    <li><a href="http://ppm.activestate.com/PPMPackages/zips/">activeperl ppm 下载</a>
    <li><a href="http://theoryx5.uwinnipeg.ca/ppmpackages/">activeperl 5.6 ppm 下载</a>
    <li><a href="http://theoryx5.uwinnipeg.ca/ppms/">activeperl 5.8 ppm 下载</a>
    <li><a href="http://crazyinsomniac.perlmonk.org/perl/ppm/">activeperl 5.6 ppm 下载</a> :如果你要的模块上面找不到的话,尝试这个
    <li><a href="http://crazyinsomniac.perlmonk.org/perl/ppm/5.8/">activeperl 5.8 ppm 下载</a> :如果你要的模块上面找不到的话，尝试这个 </li>
</ul>
</div>
</div>
</div>
</div>
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:15 <a href="http://www.cnitblog.com/ttyuren/articles/27187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Perl 与数学：一份快速参考</title><link>http://www.cnitblog.com/ttyuren/articles/27186.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:12:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27186.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27186.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27186.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27186.html</trackback:ping><description><![CDATA[<div class=topbanner><img src="http://www.perlchina.org/images/logo/perlchina_org.gif"> </div>
<div id=Content>
<h1>Perl 与数学：一份快速参考</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/klaus/"><u><font color=#0000ff>klaus</font></u></a><br>出处：<a href="http://www.perlchina.org/"><u><font color=#810081>中国Perl协会</font></u></a> <a href="http://fund.perlchina.org/"><u><font color=#0000ff>FPC</font></u></a>(Foundation of Perlchina)<br>原 名：Perl &amp; Math: A Quick Reference <br>中 文：Perl 与数学：一份快速参考 <br>作 者：chunlou <br>原 文：http://www.perlmonks.org/index.pl?node_id=284324 <br>发 表：Aug 16, 2003 <br>审 校：JackyCheng <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：38分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=40#文评"><u><font color=#0000ff>[查看文评]</font></u></a></p>
            <u><font color=#0000ff>
            <hr>
            </font></u></td>
        </tr>
    </tbody>
</table>
<p><u><font color=#0000ff></font></u></p>
<div id=Container>
<div id=Content>
<div id=revision>
<h2><strong>Perl 与数学：快速指南</strong> </h2>
<p>一直都有人问讨论有关于 Perl 与数学的问题。有时候一些 perl 玩家问如何使用 perl 做一些高级数学的工作。另一方面，一些数学家又反过来问如何利用 perl 来帮助完成他们本身的工作。所以，现在我提供一些方便的参考文献，比较和说明一些常用的 perl 数学模块，以及对 perl 有用的软件。它并不是完整的Perl数学编程手册，而只是对于一些常用的数学模块和软件的简要综述。我忽略了 bioperl 以及生物信息学的内容，因为他们涵盖范围太广，无法简单地称之为&#8220;数学&#8221;。</p>
<p>一般来说，如果你在 <span class=caps>CPAN </span>上搜索与数学相关的模块，那么你应该从以下关键字入手： Math::&#215;， Statistics::&#215;， 以及 AI::&#215; ，Algorithm::&#215;， Cript::&#215;， Date::， Graph::， GraphViz::， Inline::， 等等。 <span class=caps>GNU</span>项目也是<br>寻找 perl 扩展模块的好地方。</p>
<h3><strong>Perl数学模块及其相关软件</strong></h3>
<p>以下列举了一些有关于数学的 perl 模块及软件：</p>
<table id=table1 cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td align=middle><font size=2><strong><font color=#333333>模块/软件</font></strong></font></td>
            <td align=middle><font size=2><strong><font color=#333333>类型</font></strong></font></td>
            <td align=middle><font size=2><strong><font color=#333333>可用性</font></strong></font></td>
            <td align=middle><font size=2><strong><font color=#333333>评论</font></strong></font></td>
        </tr>
        <tr>
            <td align=middle height=46><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Inline%3A%3AC"><u>Inline::C</u></a></font></td>
            <td align=middle height=46><font size=2>通用模块，perl 与 C 语言的接口</font></td>
            <td align=middle height=46><font size=2>任何操作系统</font></td>
            <td align=middle height=46><font size=2>可能不是你用 perl 做数学的第一选择</font></td>
        </tr>
        <tr>
            <td align=middle><font size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Inline%3A%3AOctave"><u><font color=#0000ff>Inline::Octave</font></u></a> &amp; <a href="http://www.octave.org/"><u><font color=#0000ff>Octave</font></u></a></font></td>
            <td align=middle><font size=2>矩阵代数以及数值分析</font></td>
            <td align=middle><font size=2>Inline::Octave 无法从ActiveState获得。 Octave 可以在任何操作系统运行</font></td>
            <td align=middle><font size=2>Matlab的开源版本，运行快，语法简单。Octave 可以交互式的使用，或用做脚本语言。 其他类似的商业软件有：Gauss，APL等。</font></td>
        </tr>
        <tr>
            <td align=middle><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Math%3A%3ACephes"><u>Math::Cephes</u></a></font></td>
            <td align=middle><font size=2>通用工程数学库</font></td>
            <td align=middle><font size=2>任何操作系统</font></td>
            <td align=middle><font size=2>特征系统（Eigensystem）仅适用与实对称矩阵。</font></td>
        </tr>
        <tr>
            <td align=middle><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Math%3A%3ALP"><u>Math::LP</u></a></font></td>
            <td align=middle><font size=2>线性编程</font></td>
            <td align=middle><font size=2>ActiveState perl 没有，LP solve则有 <span class=caps>DOS </span>的版本。</font></td>
            <td align=middle><font size=2>免费，但 <span class=caps>LP </span>Solve 可能不再持续维护了。类似的商用软件有：CPLEX，Lindo，Minos，AMPL等。</font></td>
        </tr>
        <tr>
            <td align=middle><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Math%3A%3APari"><u>Math::Pari</u></a></font></td>
            <td align=middle><font size=2>数论</font></td>
            <td align=middle><font size=2>任何操作系统</font></td>
            <td align=middle><font size=2>很适合密码学分析</font></td>
        </tr>
        <tr>
            <td align=middle><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=Math%3A%3AMatrixReal"><u>Math::MatrixReal</u></a></font></td>
            <td align=middle><font size=2>矩阵代数（仅适用用于实数）</font></td>
            <td align=middle><font size=2>任何操作系统</font></td>
            <td align=middle><font size=2>纯 Perl 代码实现，特征系统仅用于实对称矩阵</font></td>
        </tr>
        <tr>
            <td align=middle><font color=#0000ff size=2><a href="http://search.cpan.org/search?mode=module&amp;query=PDL"><span class=caps><u>PDL</u></span></a></font></td>
            <td align=middle><font size=2>Perl 数据语言（Perl Data Language）</font></td>
            <td align=middle><font size=2>最新版本为2.4.0，windows预编译版2.3.1。</font></td>
            <td align=middle><font size=2>为 perl 提供更多的数学语法</font></td>
        </tr>
        <tr>
            <td align=middle><a href="http://www.perlmonks.org/www.r-project.org"><font color=#0000ff size=2><u>R</u></font></a></td>
            <td align=middle><font size=2>Statistical software</font></td>
            <td align=middle><font size=2>任何操作系统</font></td>
            <td align=middle><font size=2>可交互式使用或作为脚本语言使用。在作图方面非常出色（可以参考<a href="http://www.ipd.uka.de/EIR/otherwork/jccpprt_computer2000.pdf"><u><font color=#0000ff>这里</font></u></a>）最新版本1.7.1（译者注：本文翻译的时候的最新版本为2.1.0）是Splus的开源版本。可作为 windows 系统的双向&#8220;nix &amp; <span class=caps>COM</span>&#8221;服务器界面（从R v.1.7.0开始）引自 <a href="http://www.perlmonks.org/www.omegahat.org"><u><font color=#0000ff>Omegahat</font></u></a>。类似的商业软件：SPSS，SAS等。<br>　</font></td>
        </tr>
    </tbody>
</table>
<h2>　</h2>
<h3><strong>语法比较</strong></h3>
<p>我们来比较一下这些模块和软件的语法。我们以运算一个2&#215;2矩阵与一个向量的乘积为例，以下是它们各自的语法。</p>
<table id=table2 cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td align=middle><font size=2><strong><font color=#333333>模块/软件</font></strong></font></td>
            <td align=middle><font size=2><strong><font color=#333333>代码</font></strong></font></td>
        </tr>
        <tr>
            <td align=middle><font size=2>Math::Cephes</font></td>
            <td>
            <pre>use Math::Cephes::Matrix qw(mat);
            $a = mat [[1, 2], [3, 4]];
            $b = [1, 1];
            print "@{$a-&gt;mul($b)}";
            # print "3 7"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>Math::RealMatrix</font></td>
            <td>
            <pre>use  Math::MatrixReal;
            $a = Math::MatrixReal-&gt;new_from_rows( [[1, 2], [3, 4]] );
            $b = Math::MatrixReal-&gt;new_from_cols( [ [1, 1] ] );
            print $a*$b;
            # print "[  3.000000000000E+000 ]
            #        [  7.000000000000E+000 ]"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2><span class=caps>PDL</span></font></td>
            <td>
            <pre>use PDL;
            $a = pdl [[1, 2],[3, 4]];
            $b = pdl [[1], [1]];
            print $a x $b;
            # print "[
            #         [3]
            #         [7]
            #        ]"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>Octave</font></td>
            <td>
            <pre>&gt;&gt; a = [1, 2; 3, 4];
            &gt;&gt; b = [1; 1];
            &gt;&gt; a*b
            ans =
            3
            7
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>R</font></td>
            <td>
            <pre>&gt; a = matrix(c(1,2,3,4), ncol=2, byrow=T)
            &gt; b = matrix(c(1,1), ncol=1)
            &gt; a%*%b
            [,1]
            [1,]    3
            [2,]    7
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<p>仅就数学上来说，以上这些模块和软件的语法看起来都相当简洁。不过 Octave 和 R 比 perl 还是要好懂的多了。许多数学语言的一个突出特点是它们的&#8220;向量操作&#8221;以及&#8220;下标操作&#8221;。</p>
<p>具个例子来讲，例如现在我们要从一个矩阵中，提取一个子矩阵。</p>
<h2>实例：提取一个子矩阵</h2>
<table id=table3 cellSpacing=0 cellPadding=3 width=558 border=1>
    <tbody>
        <tr>
            <td align=middle><font size=2><strong><font color=#333333>模块/软件</font></strong></font></td>
            <td align=middle><font size=2><strong><font color=#333333>代码</font></strong></font></td>
        </tr>
        <tr>
            <td align=middle><font size=2>Math::Cephes</font></td>
            <td>
            <pre>use Math::Cephes::Matrix qw(mat);
            $mat = mat [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
            $mat = $mat-&gt;coef;
            for my $i (1..2) {   # 0 first index
            print "@{$mat-&gt;[$i]}[1..2]\n";
            }
            # print "5 6
            #        8 9"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>Math::RealMatrix</font></td>
            <td>
            <pre>use  Math::MatrixReal;
            $mat = Math::MatrixReal-&gt;new_from_rows(
            [[1, 2, 3], [4, 5, 6], [7, 8, 9]] );
            for my $i (2..3) {   # 1 first index
            for my $j (2..3) {
            print $mat-&gt;element($i, $j), " ";
            }
            print "\n";
            }
            # print "5 6
            #        8 9"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2><span class=caps>PDL</span></font></td>
            <td>
            <pre>use PDL;
            $mat = pdl [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
            print $mat-&gt;slice("1:2,1:2");   # 0 first index
            # print "[
            #         [5 6]
            #         [8 9]
            #        ]"
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>Octave</font></td>
            <td>
            <pre>mat = [1,2,3; 4,5,6; 7,8,9];
            mat(2:3, 2:3)
            ans =
            5        6
            8        9
            </pre>
            </td>
        </tr>
        <tr>
            <td align=middle><font size=2>R</font></td>
            <td>
            <pre>&gt; mat = matrix(1:9, ncol=3, byrow=T)
            &gt; mat[2:3, 2:3]
            [,1] [,2]
            [1,]    5    6
            [2,]    8    9
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<p>向量的串行运算是一个非常不错的功能. 考虑一下下面的有关于 R 的源码:</p>
<pre>&gt; vec = 1:10
&gt; vec
[1]  1  2  3  4  5  6  7  8  9 10
&gt; vec %% 2
[1] 1 0 1 0 1 0 1 0 1 0
&gt; vec[vec %% 2 == 1]
[1] 1 3 5 7 9
&gt; vec[vec %% 2 == 1] + 1
[1]  2  4  6  8 10
</pre>
<p>我们刚才在前面也提到了 Pari，但它只是一个自成体系的模块。我们来看一个 Pari 的例子。</p>
<pre>#! /usr/local/bin/perl -w
use strict;
# -----------------------------------------------------------
#     RSA algorithm -- assymetrical\public-key cryptography
# -----------------------------------------------------------
use Math::Pari qw(gcd PARI) ;
# -----------------------------------------------------------
# m -- message
my $m = 'Perl' ;
print "original: $m\n" ;
my $tmpl = 'C*' ;
my @m = unpack($tmpl, $m) ;       # string -&gt; unsigned char values
print "coded: @m\n" ;
# n = pq -- in RSA, p &amp; q = prime, each 1024 bits/308 digits long
my $p = PARI("prime(".int(rand 50).")") ;
my $q = PARI("prime(".int(rand 50).")") ;
my $n = $p*$q ;            # $n = Pari's obj
# choose a random number r, s.t.
#     1 &lt; r &lt; (p-1)(q-1) = b
#     gcd(r, b) = 1 -- relative prime
my $b = ($p-1)*($q-1) ;
my $r ;
do {$r = int rand $b ; } until (gcd($r,$b) == 1) ;
$r = PARI $r ;
# rk = 1 mod (p-1)(q-1) -- k = private key; (n, r) public
my $k = (1/$r)%$b ;        # Pari's math operators, since vars = Pari
# encrypt -- c = (m ^ r) mod n
my @c ;
map { $c[$_] = ($m[$_]**$r)%$n } 0..$#m ;   # Perl: ** for power
print "ciphered: @c\n" ;
# decrypt -- m = (c ^ k) mod n
my @d ;
map { $d[$_] = PARI("($c[$_]^$k)%$n") } 0..$#c ;   # Pari: ^ for power
print "deciphered: @d\n" ;
print "decoded: " . pack($tmpl, @d) . "\n" ;
__END__
original: Perl
coded: 80 101 114 108
ciphered: 18431 6512 5843 7236
deciphered: 80 101 114 108
decoded: Perl
&lt;/font&gt;&lt;/tt&gt;</pre>
<p>有时侯 perl 和数学软件之间并没有直接的相互接口，但是那些软件可以通过命令行来运行，于是我们就可以利用命令行界面来操作他们。以下是 perl 与 R 之间的一个例子：</p>
<pre>&lt;tt class="code"&gt;&lt;font size="-1"&gt;#! /usr/local/bin/perl -w
use strict ;
R("getwd()");
sub R {
my $Rpath = "C:\R\rw\bin\" ;
my $Rcmd = $Rpath . "rterm --vanilla --quiet --slave" ;
my $Rscript = shift ;
$Rscript =~ s/(\r|;\r)/ ;/gm ;
$Rscript =~ s/&lt;-/=/gm ; # \r or &lt;- will break "echo"
return `echo $Rscript | $Rcmd` ;
}
</pre>
<p>如果你只有 <span class=caps>DOS LP </span>Solce 的可执行程序，那么你也可以这样操作：</p>
<pre>my $dir = 'D:\tmp\prog\math\lp32';
my $lp_solve = "d:\mydir\lp_solve.exe";
my $lpfile = "d:\mydir\model.lp";
(my $lp = &lt;&lt; "    EOF") =~ s/^\s+//gm;
min: 8  x1 + 15 x2       ;
c1:  10 x1 + 21 x2 &gt; 156 ;
c2:  2  x1 +    x2 &gt; 22  ;
EOF
open OUTFILE, "+&gt;$lpfile";
print OUTFILE $lp;
close OUTFILE;
$output = qx($lp_solve &lt; $lpfile);
$output =~ s/\r//gm;
print $lp;
print $output;
system("del $lpfile");
</pre>
<p>这也是为什么 Perl 被成为&#8220;胶水语言&#8221;的原因。</p>
<h3><strong>评测</strong></h3>
<p>人们做数学的时候往往很关心速度，所以我们来做些评测。</p>
<pre>use strict;
use warnings;
my ($a1,$a2,$a3,$ref);
for my $x (0..20) {
for my $y (0..20) {
$ref-&gt;[$x][$y] = rand 100;
}
}
use Math::Cephes::Matrix qw(mat);
$a1 = mat $ref;
use  Math::MatrixReal;
$a2 = Math::MatrixReal-&gt;new_from_rows( $ref );
use PDL;
use PDL::Slatec;
$a3 = pdl $ref;
use Benchmark qw(cmpthese);
cmpthese(100,
{
cephes=&gt;sub{$a1-&gt;inv()},
matrixreal=&gt;sub{$a2-&gt;inverse()},
pdl=&gt;sub{matinv($a3)}
}
);
__END__
Rate matrixreal     cephes        pdl
matrixreal 5.28/s         --       -94%       -99%
cephes     83.3/s      1479%         --       -87%
pdl         625/s     11744%       650%         --
</pre>
<p>注意，对于任何编译的数学模块，编译的方式将对计算速度有着非常大的影响。关于此，你可以在<a href="http://www.sciviews.org/other/benchmark.htm"><u><font color=#0000ff>这里</font></u></a>找到Octave 和 R 以及其他一些数学工具的评测。</p>
<p>假如你不太清楚 Perl 和其他数学软件与模块如何写作来完成一个项目，以下是一些提示（但不是规定）。</p>
<table id=table4 cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td align=middle width=27><font color=#333333><span style="FONT-WEIGHT: 700; FONT-SIZE: 9pt">流程</span></font></td>
            <td align=middle><strong><font style="FONT-SIZE: 9pt" color=#333333>Perl</font></strong></td>
            <td align=middle><strong><font style="FONT-SIZE: 9pt" color=#333333>数学模块/软件</font></strong></td>
            <td align=middle width=596><strong><font style="FONT-SIZE: 9pt" color=#333333>评论</font></strong></td>
        </tr>
        <tr>
            <td align=middle width=27><strong><font style="FONT-SIZE: 9pt" color=#000000>数据存储</font></strong></td>
            <td align=middle>
            <p align=center><font style="FONT-SIZE: 9pt" color=#333333>N/A</font></p>
            </td>
            <td align=middle><font style="FONT-SIZE: 9pt" color=#333333>N/A</font></td>
            <td align=left width=596>
            <p align=left><font size=2>很多人用电子表格存储数据。不过可能用数据库会更好些，比如Oracle，MySQL，MS <span class=caps>SQL</span>等等。这部分工作和 Perl 和数学工具都关系不太大。</font></p>
            </td>
        </tr>
        <tr>
            <td align=middle width=27><strong><font style="FONT-SIZE: 9pt" color=#000000>数据存取</font></strong></td>
            <td align=middle><u><strong><span style="FONT-SIZE: 9pt"><font color=#ff0000>是</font></span></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt" color=#333333>可能</font></td>
            <td align=left width=596><font size=2>这部分工作是&#8220;插入&#8221;，&#8220;更新&#8221;和&#8220;删除&#8221;数据。你可能会用<a href="http://search.cpan.org/search?mode=module&amp;query=DBI"><span class=caps><u><font color=#0000ff>DBI</font></u></span></a> 来做这件事。如果你的数学软件可以直接完成这些数据操作的工作，那部分就不再需要 Perl 了。</font></td>
        </tr>
        <tr>
            <td align=middle width=27><strong><font style="FONT-SIZE: 9pt" color=#000000>数据操作</font></strong></td>
            <td align=middle><u><strong><span class=caps><span style="FONT-SIZE: 9pt"><font color=#ff0000>YES</font></span></span></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt" color=#333333>可能</font></td>
            <td align=left width=596><font size=2>数据操作的意思是以正确的格式获取原始数据以用于数据分析。比如从 log 文件中提取一系列的时间，把一些格式混乱的文本文件转换为 <span class=caps>CSV </span>文件，等等。当这项工作变得复杂的时候，Perl 可能比直接操作电子表格或者数学软件方便得多，同时你可能会用到很多<strong>正则表达式</strong>。</font></td>
        </tr>
        <tr>
            <td align=middle width=27 height=65><strong><font style="FONT-SIZE: 9pt" color=#000000>数据分析</font></strong></td>
            <td align=middle height=65><font style="FONT-SIZE: 9pt" color=#333333>可能</font></td>
            <td align=middle height=65><u><strong><span style="FONT-SIZE: 9pt"><font color=#333333>是</font></span></strong></u></td>
            <td align=left width=596 height=65><font size=2>在做复杂数学运算的时候， Perl 没有 C 那么快的速度，也没有 Octave 或其他数学模块那样简单的语法，所以数据分析的部分常常是由专业的数学软件完成的。当然，如果你大部分工作都是用的 Perl，而你需要的数学又相对简单，那么再去求助专业软件就可能是杀鸡用牛刀了。</font></td>
        </tr>
        <tr>
            <td align=middle width=27><strong><font style="FONT-SIZE: 9pt" color=#000000>生成报表</font></strong></td>
            <td align=middle><u><strong><span style="FONT-SIZE: 9pt"><font color=#333333>是</font></span></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt" color=#333333>可能</font></td>
            <td align=left width=596>
            <p align=left><font size=2>一些数据库（如Oracle）或数学/统计学软件（比如SAS）提供&#8220;报表生成器&#8221;。如果这些能够满足你的要求，那么你就用它好了。但是如果你需要更复杂的报告，Perl 可能是你的选择。</font> <font size=2>你经常会用 Perl 来创建 <span class=caps>HTML </span>格式的报告（比其他格式如 <span class=caps>PDF </span>要简单得多），然后将 <span class=caps>HTML </span>再转换成其他格式，比如 <span class=caps>WORD </span>或 <span class=caps>PDF</span>。有些人会更关心 <span class=caps>XML</span>。XML实际上是展示数据的一种方法，但不是用来做视觉上的数据展示。用设计与开发的术语来说，XML 可能更接近于数据存储，而离数据报表更远。数据存储的工作是你应该在整个项目早期考虑的事情，而不是在数据汇报的时候。</font></p>
            </td>
        </tr>
    </tbody>
</table>
<p>越来越多的人，通过互联网来获取数据，例如 <span class=caps>XML </span>等格式，然后对这些数据进行分析（股票数据，DNA 数据，等等）。</p>
<table id=table5 cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td>　</td>
            <td align=middle><strong><font style="FONT-SIZE: 9pt" color=#000000>Perl</font></strong></td>
            <td align=middle><strong><font style="FONT-SIZE: 9pt" color=#000000>数学模块/软件</font></strong></td>
            <td align=middle><strong><font style="FONT-SIZE: 9pt" color=#000000>可能用到的工具</font></strong></td>
        </tr>
        <tr>
            <td><strong><span class=caps><span style="FONT-SIZE: 9pt"><font color=#000000>XML </font></span></span><span style="FONT-SIZE: 9pt"><font color=#000000>获取</font></span></strong></td>
            <td align=middle><u><strong><font style="FONT-SIZE: 9pt" color=#ff0000>是</font></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt">可能</font></td>
            <td align=middle>
            <p align=center><a href="http://search.cpan.org/search?mode=module&amp;query=LWP"><span class=caps><span style="FONT-SIZE: 9pt"><u><font color=#0000ff>LWP</font></u></span></span></a><span style="FONT-SIZE: 9pt">, </span><a href="http://search.cpan.org/search?mode=module&amp;query=XML%3A%3AlibXML"><span style="FONT-SIZE: 9pt"><u><font color=#0000ff><span class=caps>XML</span>::libXML</font></u></span></a></p>
            </td>
        </tr>
        <tr>
            <td><span style="FONT-WEIGHT: 700; FONT-SIZE: 9pt">数据处理</span></td>
            <td align=middle><u><strong><font style="FONT-SIZE: 9pt" color=#ff0000>是</font></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt">可能</font></td>
            <td align=middle><span style="FONT-SIZE: 9pt">正则表达式</span></td>
        </tr>
        <tr>
            <td><span style="FONT-WEIGHT: 700; FONT-SIZE: 9pt">数据分析</span></td>
            <td align=middle><font style="FONT-SIZE: 9pt">可能</font></td>
            <td align=middle><u><strong><font style="FONT-SIZE: 9pt" color=#ff0000>是</font></strong></u></td>
            <td align=middle><span style="FONT-SIZE: 9pt">前面提到的软件或工具</span></td>
        </tr>
        <tr>
            <td><span style="FONT-WEIGHT: 700; FONT-SIZE: 9pt">汇总报告</span></td>
            <td align=middle><u><strong><font style="FONT-SIZE: 9pt" color=#ff0000>是</font></strong></u></td>
            <td align=middle><font style="FONT-SIZE: 9pt">可能</font></td>
            <td align=middle><a href="http://search.cpan.org/search?mode=module&amp;query=%26nbsp%3BText%3A%3ATemplate"><span style="FONT-SIZE: 9pt"><u><font color=#0000ff>Text::Template</font></u></span></a><span style="FONT-SIZE: 9pt">, <a href="http://search.cpan.org/search?mode=module&amp;query=HTML%3A%3ATemplate"><u><font color=#0000ff><span class=caps>HTML</span>::Template</font></u></a>, </span><a href="http://search.cpan.org/search?mode=module&amp;query=XML%3A%3AlibXSLT"><span style="FONT-SIZE: 9pt"><u><font color=#0000ff><span class=caps>XML</span>::libXSLT</font></u></span></a></td>
        </tr>
    </tbody>
</table>
<p><strong><font color=#008000>以上就是本手册的全部内容，希望对你能有所帮助。</font></strong></p>
</div>
</div>
</div>
</div>
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:12 <a href="http://www.cnitblog.com/ttyuren/articles/27186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Perl 编程格式指南</title><link>http://www.cnitblog.com/ttyuren/articles/27185.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:11:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27185.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27185.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27185.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27185.html</trackback:ping><description><![CDATA[<div class=topbanner><img src="http://www.perlchina.org/images/logo/perlchina_org.gif"> </div>
<div id=Content>
<h1>Perl 编程格式指南</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/zjl_perl/"><u><font color=#0000ff>zjl_perl</font></u></a><br>出处：<a href="http://www.perlchina.org/"><u><font color=#810081>中国Perl协会</font></u></a> <a href="http://fund.perlchina.org/"><u><font color=#0000ff>FPC</font></u></a>(Foundation of Perlchina)<br>作者： <br>原名：P5EEx::Blue::perlstyle &#8211; P5EE Style Guide <br>原文：http://www.officevision.com/pub/p5ee/software/htdocs/P5EEx/Blue/perlstyle.html <br>发表： <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：135分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=52#文评"><u><font color=#0000ff>[查看文评]</font></u></a></p>
            <u><font color=#0000ff>
            <hr>
            </font></u></td>
        </tr>
    </tbody>
</table>
<p><u><font color=#0000ff></font></u></p>
<h3>名称</h3>
P5EEx::Blue::perlstyle - P5EE 样式指导 P5EE 是 Perl 5 Enterprise Environment (企业型 Perl5 样式指导）的缩写。
<h3>介绍</h3>
在P5EE发行版中,包含的所有代码和文件都遵循了本文所述的样式。请注意：这些样式并不是要抑制你的创造力，而是想要使那些阅读到你代码的家伙们的生活变得更容易一些。他也可以用来解决分歧，避免个人间纠纷。 下面的这些约定适用于perl模块，web程序（CGI/mod_perl）以及命令行程序。当然，这些规则也在一定程度上适用于用P5EE写的perl代码。 注意，这些都是指导性的方针，不是必须遵守的规则。如果在这里你真的需要违反其中一条的话，无论如何，最好先问问P5EE核心团队。 另外，本文档中的大部分，并不是强调正确的方法就是我们的方法。我们需要有一些约定来让每个人的生活更容易一些。 如果你有什么问题，可以在P5EE开发邮件列表中询问，p5ee@perl.org. http://lists.perl.org/showlist.cgi?name=p5ee P5EE项目所需文件在下面这些网站上可以找到。 http://p5ee.perl.org/ http://www.officevision.com/pub/p5ee 本文档将随时间不断更新，每份最新的文档结尾，都会有历次版本的变动记录。
<h3>编码规则</h3>
<h4>Perl版本</h4>
我们是在perl5.005_03上编写所有代码的。也许有一天我们应该利用以下perl5.6的特性。不管怎样，所有代码应该在perl5.005_03以及后续版本上都能运行。P5EE所有的核心代码都在perl5.005_03和perl5.6.0上测试过，虽然现在P5EE用在perl5.6上比较多。
<h4>文档</h4>
所有的模块文档都应参照模块模板文件中的POD例子来撰写，解释模块的方法，目的，用途和每个带有名字，描述，输入，输出，受影响因素等信息的公用API。 文档中，如果需要返回一个数组或哈希表的引用，要记录数组的大小（包括恰当地描述每个元素都是什么）和哈希表中每个键的名字。如果是复合数据结构的话，尽量描绘出合适的结构。 另外，在文档中还要记录出返回数据是什么类型的数值。是整型，还是一段HTML代码，还是一个布尔值？ 所有命令行程序的选项都要使用命令行程序样本文件中的代码来记录。每个有效的方法，switch结构等等都要被记录，连同方法的描述，目的，程序如何使用。不要尝试对不同目的的程序使用相同的选项。 对于所有的WEB程序，应当在程序注释段中说明功能，目的和使用。 任何外部文档，命令行程序和模块的文档都要写成POD样式。这样的话，我们就可以把它们通过多种pod2xxx的转换器转换成各种格式的其他文档。POD不是一种正规的标签语言，它只是一种可以让文档非常容易转换成其他格式的方法。如果你有什么问题的话，可以自己看一下Perl自带的 perlpod帮助页 或者 询问我们及其其他懂POD的人。Perl中国推广组的FPC里面，也有一篇 {fayland} 所写的关于 [[如何撰写POD]] 的文章。
<h4>版本</h4>
分别使用模块，web程序，命令行程序样本文件中版本的代码。模块中的$VERSION将会反映出CVS的版本。Makefile.PL文件应该包含版本描述，并且还应该不依赖于CVS仓库中任何一个单独文件的版本。 同样，拥有$VERSION的XS模块也会反映出发行版的版本，否则每当你对文件做了一点改动，你都需要重新编译那些已经共享的库。这对于从事开发工作中的人来讲，的确是一种痛苦。 我们的发行版本号使用tuples模式，第一个数字是主修订号，第二个数字是版本号，第三个数字是子版本号。Odd-numbered版本号是开发版本。例如：
<pre>1.0.0       P5EE 1 的首发版
1.0.1       P5EE 1.0的第二次发布版
1.0.10      P5EE 1.0的第二次发布版的第一次修正版
1.1.0       P5EE 1.1的首发版
2.0.0       P5EE 2 的首发版</pre>
版本号后面也可以跟一个连字符和一些文字，来表示特别的版本，或者给出额外的信息。例如 1.1.4-bender 注意，这是一个狂欢版 1.5.0-pre1 注意这不是最后的版本，而是预览版。 在perl5.6.0中，你可以使用象v2.0.0这样的版本，但是在前几版的perl是不允许的。所以要把一个tuple版本号转换成一个用$VERSION表示的版本号字符串，使用正常的整数来表示主修订号，三个数字来做版本号和三个数字来做子版本号。例如：
<pre><code>
1.1.6   -&gt;      1.001006
2.0.0   -&gt;      2.000000
</code></pre>
这样，perl就可以通过大于和小于比较两个版本字符串。 LinuxForum中有一篇关于 软件发行惯例 的中文译版：http://www.linuxforum.net/books/srp/Software-Release-Practice-HOWTO.html
<h4>注释</h4>
所有的代码都应该尽可能地具有可读性。所以，我们的代码中可以只包含一些对于不明朗内容的必要注释。于是，我们应该使用象&#8216;$story_count&#8217;这样的名字，而不是这么做：
<pre><code>
# story count
my $sc = 0;
</code></pre>
也许要别人理解代码需要包含一些整齐的注释。有时一个简单的单行注释就可以解释后面代码的用途。另外，我们有时还需要对一个复杂的算法需要每行都要注释。Kernighan 和 Pike 写的《Practice of Programming》中关于注释的部分值得一看。
<h4>警告和严格语法</h4>
所有代码都必须使用&#8216;use strict&#8217;和打开perl的-w选项来编译和运行。当然，如果你必须禁止 -w 或 strict 的使用，我们也是没有意见的。（实际上你真正需要这么做的机会将会很渺茫）。 有一个例外是&#8220;使用了未初始化的变量&#8221;警告，我们在P5EE.pm中禁掉了它，所以在你的代码中如何包含了&#8220;use P5EE&#8221;，那么你就不必担心这些警告了。
<h4>词汇范畴变量</h4>
只使用词汇范畴变量，除了一些特殊的全局变量（$VERSION,%ENV,@ISA,$!等等）和一些极特殊的情况。把全局变量当成普通变量从来都是不恰当的，如有必要，使用&#8220;use vars&#8221;来声明全局变量，而不是使用our()函数（our()在perl5.6中有介绍）。 词汇范畴内的变量使用my()来创建。一个全局变量是预先存在的（如果他是一个特殊变量），或者当他被使用的时候就刚刚创建。local()被用来告诉perl为一个变量赋一个临时值。这应该只用于象$/这样的特殊变量，或者在特殊的环境中。如果你必须给某个全局变量赋值的话，那么你最好先考虑考虑是否需要用local()。 local()也可以用于数组或者哈希表中的元素，尽管这很不常用。
<h4>输出</h4>
默认情况下不要从模块中输入任何东西。你可以自由地在@EXPORT_OK中放入任何你想放的东西，这样你的模块的使用者就可以明确地请求这些符号。（例如：&#8220;use P5EE::Something qw(getFoo setFoo)&#8221;），但是不要默认地输出它们。
<h4>传递引用参数</h4>
方法要获取或者返回数组和哈希表的时候最好只使用其引用。注意列表和数组不是一回事。下面这样就很好：
<pre><code>
return($user, $form, $constants);
</code></pre>
当数组不确定的时候也许是一个例外。
<pre><code>
my @return = ($user, $form);
push @return, $constants if $flag;
return @return;
</code></pre>
尽管如此，但是，为了提高代码的效率和可读性，我们更趋向于编写这样的代码：
<pre><code>
if ($flag) {
return($user, $form, $constants);
} else {
return($user, $form);
}
</code></pre>
<h4>垃圾收集</h4>
perl在垃圾收集方面的确作的很好。它会自动清理那些过了生存期的词汇范畴变量和已经没有引用计数的对象。如果你使用词汇范畴的话，通常你不必担心这个。 然而，有一些粘合的代码，比如用C编译的代码连接到perl，perl也许就不会自动帮你清理了。在这种情况下，你就得自己动手了。如果在那些粘合的代码中有实现此功能的方法，那么使用这些方法是比较适合的。 还有，如果你有一个运行时间会很长的函数，里面有一个巨大的数据结构。那么希望你尽可能地在它运行完之后立刻释放一下内存。
<pre><code>
my $huge_data_structure = get_huge_data_structure();
do_something_with($huge_data_structure);
undef $huge_data_structure;
</code></pre>
<h4>__END__ 和 __DATA__ 和 __PACKAGE__</h4>
在web程序中不要使用__END__或者__DATA__。它们会与mod_perl冲突。还有，在web程序中__PACKAGE__也许不会返回你期望的值。但它们在模块中运行良好。
<h4>测试</h4>
模块应该提供测试代码，还有如何使用它们的文档。
<h4>STDIN/STDOUT</h4>
永远使用P5EE的日志工具来报错。不要直接打印到STDERR上。也不要直接打印到STDOUT上。除非你需要直接打印到用户的浏览器上。 在命令行程序中，根据你的需要打印到STDERR或STDOUT上都可以。
<h4>文件和Globs</h4>
为了建立和分析文件路径，请使用Filel::Spect::Functions 和 File::Basename 模块。要创建和销毁路径，使用File::Path模块。这在非Unix平台中比较方便。
<pre><code>
my $path = "$dir/$file";                # 错
my $path = catfile($dir, $file);        # 对
my $dir = ".";                          # 错
my $dir = curdir();                     # 对
mkdir("/path"), mkdir("/path/to"), ...  # 错
`mkdir /path`; `mkdir /path/to`, ...    # 大错特错
mkpath("/path/to/my/dir", 0, 0775);     # 对
</code></pre>
请使用<code> opendir() </code>和<code> readdir() </code>来代替 glob 操作符<code>（glob('*') 或者 &lt;*&gt;）</code>。注意<code> glob() </code>在perl5.6中比以往版本更轻便了，但它还是不十分可靠，每个perl的安装都可以选择通过<code> File::Glob</code> 模块来用本地的习惯来代替这个默认的。 不要为了任何事而使用向*foo这样的符号表 globs（和上面提到的 glob 不一样），除非有必要必须直接操作符号表。其实这从来都是不必要的。
<h4>系统调用</h4>
永远都要在系统调用后检查返回值。包括 open()，close()，mkdir() 或者其他直接面对系统的对话。perl内置的系统调用都会把错误信息返回到$!；模块中的一些方法可能会将错误返回到$@或者其他地方，如果你不知道的话就去查模块的文档。永远要这么做，哪怕只是调用一个 errorLog()，当返回的值不是你期望那样的时候。
<h3>样式</h3>
很多样式的描述都是取自perl样式man文档。我们在这里做了一些改动，但读一读那些文档也是个不错的主意。
<h4>术语</h4>
P5EE项目的名字叫做&#8220;P5EE&#8221;，并没有&#8220;P5EE1&#8221;或者&#8220;P5EE2&#8221;，要说明版本的话，使用&#8220;P5EE 2.0&#8221;或者&#8220;P5EE2.0.1&#8221;。 函数&#8217;与&#8216;子程序&#8217;与&#8216;方法&#8217;的区别： *&#8216;方法&#8217;应该只用于指向对象方法或者类的方法；也就是那些使用面向对象编程的，第一个参数是对象或者是类的函数。通常意义上的*&#8216;子程序&#8217;，它们不是对象或者类的方法，而是函数。类中创建和返回对象的方法称为构造器。
<h4>名字</h4>
不要使用一个字符的变量，除非是迭代中的指示变量。也不要使用两个字符的变量，这和使用一个字符的变量没区别。常量全部都大写；这些是在整个程序中都不会变化的变量。
<pre><code>
$Minimum = 10;          # 错
$MAXIMUM = 50;          # 对
</code></pre>
其他变量小写，用下划线来连接单词。这些单词通常都用名词（一般都是单数名词），除非变量被用来指示某些动作的标记，那么这些变量的名字可以使用描述该动作的动词（或者是动名词）。
<pre><code>
$thisVar      = 'foo';  # 错
$this_var     = 'foo';  # 对
$work_hard    = 1;      # 对，动词，布尔类型的标记
$running_fast = 0;      # 对，动名词，布尔类型的标记
</code></pre>
数组和哈希应该是复数的名词，不管是正常的数组和哈希还是数组引用和哈希引用。不要给引用命名为ref或者将其类型加入到名字当中。
<pre><code>
@stories     = (1, 2, 3);      # 对
$comment_ref = [4, 5, 6];      # 错
$comments    = [4, 5, 6];      # 对
$comment     = $comments-&gt;[0]; # 对
<code></pre>
让名字易理解。不要使用象$sc这样的名字，你应该用&#8220;$story_count&#8221;。 方法和函数（除了那些特殊情况，比如AUTOLOAD）应该由动词开头，然后后面跟着完成动作的词汇。词组组成的名字应该全部小写，并用下划线来连接单词，为了跟&#8216;perl样式&#8217;指导还有那些CPAN上大部分模块保持一致。这些方法应该尽可能地描绘出它要执行什么，和它要返回什么数据。
<pre><code>
$obj-&gt;getStory();             # 错
$obj-&gt;setStoryByName();       # 又错了
$obj-&gt;getStoryByID();         # 还是错！这不是Java！
$obj-&gt;get_story();            # 对
$obj-&gt;set_story_by_name();    # 对
$obj-&gt;get_story_by_id();      # 对
</code></pre>
以下划线开头的方法和函数是特殊的：它们在当前文件之外是无法使用的。（也就是&#8216;private&#8217;--私有的）。但这不是代码本身强制要求的，而只是编程人员的习惯而已。 对于大的for循环结构，不要使用$_，而是用具名的变量。不要用$_（或者假想它）除非你非常明确是怎么回事，或者需要它的时候（比如在map()和grep()中）。
<pre><code>
for (@list) {
print;              # 对；每个人都知道这是什么意思
print uc;           # 不好；很少有人知道这个
print uc $_;        # 看起来好一些了
}
</code></pre>
注意，如果可能的话，请使用特殊变量&#8216;_&#8217;。它是一个占位符，可以传递给stat()和文件测试符，它让重新判断文件的状态变得简单一些。在下面这个例子中。在每个文件测试中都要使用变量$file。使用&#8216;_&#8217;来代替是个不错的选择。尽管最后一次测试的文件和你想像的一样，你还是应该小心一些。
<pre><code>
if (-d $file) {   # $file现在是一个目录
# ...
} elsif (-l _) {  # $file现在是一个symlink        # ...
}
</code></pre>
包的名字应该每个单词的第一个字母大写，其余的小写。
<pre>    P5EE::Standard          # 　好
P5EE::Authz             # 　好
P5EE::MainCode          # 　好
</pre>
在POD文档中全部使用小写。
<pre>    P5EE::styleguide        # 对于文档来说还不错
</pre>
为模块命名应该遵循下面几条规则。 所有被p5ee@perl.org邮件列表广泛支持的P5EE的服务都应该进入P5EE的包中 &#8216;命名样式&#8217;应该和CPAN上的模块类似。 &#8216;选择命名&#8217;借鉴CPAN上其他模块的先例。 &#8216;选择命名&#8217;借鉴J2EE的先例。 那些还没有确定要作为对象被初始化的包应该用一个&#8216;形容词&#8217;或者&#8216;概念&#8217;来作名字（也就是 P5EE::Standard）那些已经确定要作为对象被促使化的模块和类包应该用伴有隐含变化形容词含义的名词来作名字（也就是说 P5EE::Authen::Principal）。
<h4>缩进</h4>
代码检验后进入CVS必须不能包含制表符。带有制表符的代码片断不能很好的通过email传递，而且不同的人对制表符拦截有不同的设置。如果你想为你的编辑器设置制表符拦截，只要保证它保存文件的时候，把制表符转换为空格就可以了。 一般块样式代码应该缩进4个空格。Emacs和vim的设置如下。
<pre><code>
* x?emacs: cperl-mode
.xemacs/custom.el:
------------------
(custom-set-variables
'(cperl-indent-level 4)
'(cperl-continued-statement-offset 4)
'(cperl-tab-always-indent t)
'(indent-tabs-mode nil)
)
* vim
.vimrc:
-------
set expandtab " replaces any tab keypress with the appropriate number of spaces
set tabstop=4 " sets tabs to 4 spaces
" 将制表符换成适当数量的空格
" 将制表符换成4个空格
</code></pre>
<h4>行的长度</h4>
行的最长长度应该是77列（对未折行的应该有75列），这是为了最大限度地适用于不同人的开发环境和为了更好的用email来传输而适应不同的email客户端。（也为了补丁）。 例如：Eudora3.0.6 会在第76个字符处，使用一行实心线来限制第80个非空白字符的输出。如果行中间有空格，则它允许在最后一个词后自动换行到下一个具有78个字符的行中。如果源文本没有一行超过77个字符的情况，那么&#8220;diff -u&#8221;命令则会添加一列，当然这列是不会被折行的。
<h4>空白</h4>
在结束句子的分号之前不要留空白。
<pre><code>
foo(@bar) ;     # 错
foo(@bar);      # 对
</code></pre>
垂直对齐。
<pre><code>
my $foo   = 1;
my $bar   = 2;
my $xyzzy = 3;
open(FILE, $fh)   or die $!;
open(FILE2, $fh2) or die $!;
$rot13 =~ tr[abcedfghijklmnopqrstuvwxyz]
[nopqrstuvwxyzabcdefghijklm];
# note we use a-mn-z instead of a-z,
# for readability
$rot13 =~ tr[a-mn-z]
[n-za-m];
</code></pre>
为了增加可读性，下列操作时需要一些空白： * 在做不同工作的代码块间，添加空行。 * 在变量声明完成之后，添加空行。 * 在最终的return()代码之前，添加空行。 * 在块的前面和后面添加空行，如果前面是注释的话，则不用添加空行。 一个例子：
<pre><code>
# this is my function!  这是我的函数
sub foo {
my (@data) = @_;
my $obj = new Constructor;
my ($var1, $var2);
$obj-&gt;setFoo($data[1]);
$var1 = $obj-&gt;getFoo(1);
$var2 = $obj-&gt;getFoo($var1);
display($var1, $var2);
return($data[0]);
}
print 1;
</code></pre>
<h4>圆括号</h4>
在流程结构中，在关键词和圆括号对之间要有空格。但对于函数，则不必。
<pre><code>
for(@list)         # 错
for (@list)        # 对
my ($ref)          # 对
my($ref)          # 首选
localtime ($time); # 错
localtime($time);  # 对
</code></pre>
对带圆括号的列表和标量上下文要仔细！
<pre><code>
my @array = ('a', 'b', 'c');
my ($first_element) = @array;           # a
my ($first_element) = ('a', 'b', 'c');  # a
my $element_count  = @array;            # 3
my $last_element   = ('a', 'b', 'c');   # c
</code></pre>
永远在函数后面加上圆括号，尽管没有参数也是如此。但有一些例外，比如列表操作符（比如print）和一元操作符（像undef，delete，uc等等）。 如果为了可读性，可以在圆括号中添加空格，否则不要添加。
<pre><code>
for ( map { [ $_, 1 ] } @list )     # 可以
for ( @list )                       # 也还可以。
</code></pre>
在多行的表达式中，用开始的语句或前圆括号来对齐后圆括号都可以。
<pre><code>
@list = qw(
bar
baz
);              # 正确
if ($foo &amp;&amp; $bar &amp;&amp; $baz
&amp;&amp; $buz &amp;&amp; $xyzzy
) {
print $foo;
}
</code></pre>
在后圆括号之后是否添加空格取决于它后面要跟什么。
<pre><code>
print foo(@bar), baz(@buz) if $xyzzy;
</code></pre>
还要注意，在允许省略圆括号的情况下－单行控制流程表达式，比如if $xyzzy，对于程序员来说，如果你十分明确它的含义的话，你可以省略圆括号。其实在上面的这种情况在$xyzzy两边是完全可以省略掉圆括号的。所以就省略掉它们，以增加可读性。如果有问题的话，那最好就别省略圆括号了。 同样原则也适用于perl的内置函数，当你很确定的情况下（例如，在语句中只有一句调用函数的语句，或者函数调用被流控制操作符分割）。用户自定义函数必须加上圆括弧。
<pre><code>
print 1, 2, 3;                          # 好的
delete $hash{key} if isAnon($uid);      # 好的
</code></pre>
不管怎样，如果有什么疑惑的情况，最好加上圆括弧，记住perl样式man文档中Larry Wall的一句话： 当你有疑惑的时候，加上圆括号，至少，它可以让一些可怜的笨家伙在vi中能用%跳舞。（在vi中%用来寻找匹配的括号） 尽管你不处于疑惑之中，将来使用你的代码的人，就算是为他们的大脑神经做做公益事业，你还是加上圆括号吧，省得将来他们自己加括号也许会加错地方。 所以，当程序员非常清楚的情况下，省略圆括号，但是如果有任何问题的话，就不要省略它们。
<h4>花括号</h4>
（这是关于流程控制中的花括号，不是哈希等数据结构中的花括号。） 在前花括号之前一定有一个空格
<pre><code>
while (&lt;$fh&gt;){      # 错
while (&lt;$fh&gt;) {     # 对
<code></pre>
一行的代码块可以写在一行中。那代码后面的分号可以省略。
<pre>    for (@list) { print }
</pre>
否则，在每一行代码结束的地方添加分号，在第一行写关键字和前花括号，后花括号和后面的关键字写在一行。
<pre>    for (@list) {
print;
smell();
}
</pre>
perl样式中常用&#8220;单臂elses&#8221;：（译者注：就是else旁边只有一个单花括号。）
<pre><code>
# 对
if ($foo) {
print;
}
else {
die;
}
# 错
if ($foo) {
print;
} else {
die;
}
</code></pre>
<h4>操作符</h4>
多数操作符两边可以添加空格。主要的例外是从美学角度出发的；例如，&#8220;**&#8221;符号两边的空格是省略的。另外，在&#8220;,&#8221;的前面没有空格，而在后面往往有一个空格。
<pre>   print $x , $y;   # 错
print $x, $y;   # 对
$x = 2 &gt;&gt; 1;    # 好
$y = 2**2;      # 好
</pre>
注意&#8220;&amp;&amp;&#8221;和&#8220;||&#8221;的优先级高于&#8220;and&#8221;和&#8220;or&#8221;。除此之外完全相同。建议使用低优先级的来控制流程，高优先级的用来测试/返回值。例如：
<pre>    $bool = $flag1 or $flag2;       # 错误！无法运行
$value = $foo || $bar;          #  正确
open(FILE, $file) or die $!;
$true  = foo($bar) &amp;&amp; baz($buz);
foo($bar) and baz($buz);
</pre>
注意上面&#8220;and&#8221;很少使用and，因为上面的语句比用&#8220;if&#8221;写要好一些。
<pre>    baz($buz) if foo($bar);
</pre>
大多数情况下，and和&amp;&amp;，or和||之间的混淆可以通过使用圆括号很好地解决。如果你不使用圆括号，那么你必须正确使用操作符。但如果你使用了圆括号－－通常，如果有问题的话，应该使用－－那么不管你用什么操作符都关系不大。从易读角度来看也好，从美学角度来看也好，一定要在你的代码块中保持风格一致。 在很长的代码行中在操作符之后断行，但&#8220;and&#8221;，&#8220;or&#8221;，&#8220;&amp;&amp;&#8221;，&#8220;||&#8221;例外。对于二元的操作符来讲，符号两边的数据要尽量保持整齐。
<pre>    print "foo" . "bar" . "baz"
. "buz";                    # 错
print "foo" . "bar" . "baz" .
"buz";                      # 对
print $foo unless $x == 3 &amp;&amp; $y ==
4 &amp;&amp; $z == 5;               # 错
print $foo unless $x == 3 &amp;&amp; $y == 4
&amp;&amp; $z == 5;                 # 对
</pre>
<h4>其他</h4>
在括号或者花括号中间有复合下标索引时，在两边加上空格，
<pre>    $foo{$bar{baz}{buz}};       # 不错
$foo{ $bar{baz}{buz} };     # 更好
</pre>
总的来说，单引号之间表示是纯字符，双引号之间表示是允许内插的文本。 在花括号之间的名称和当使用=&gt;符号的情况下可以省略引号，但是一定要小心这个名称不要和函数名重复。如果有重复，则必须使用引号。
<pre>    $what{'time'}{it}{is} = time();
</pre>
当创造复合语句的时候，把主要的执行动作放在前面。
<pre>    open(FILE, $fh) or die $!;      # 对
die $! unless open(FILE, $fh);  # 错
print "Starting\n" if $verbose; # 对
$verbose &amp;&amp; print "Starting\n"; # 错
</pre>
使用&#8220;打印至&#8221;来代替重复使用print语句。
<pre>        print &lt;<eot; This is a whole bunch text. like it. I don?t need to worry about messing with lots of print statements and lining them up. EOT
<pre>
只要记住，除非你在&#8220;打印至&#8221;的记号两边写上单引号（&lt;&lt;'EOT'），那么其间的文本是可以内插的。所以要打印&#8220;$&#8221;和&#8220;@&#8221;符号是需要转义的。
<h3>致谢</h3>
这篇样式指导是以slashcode样式指导为基础。
它也和mod_perl样式指导保持一致，它是C语言阿帕奇样式指导中的精华。
http://slashcode.com/docs/slashstyle.html
http://cvs.apache.org/viewcvs.cgi/modperl-docs/src/devel/modperl_style/modperl_style.pod?rev=1.5
http://dev.apache.org/styleguide.html
最新中译版在Perl中国推广组FPC中会随时更新。
<h3>更新</h3>
$Log: perlstyle.pod,v $
Revision 1.2  2001/11/30 16:00:52  spadkins
Renamed 'Component' to 'Service' throughout. Improved perldocs.
Revision 1.1  2001/11/22 05:16:59  spadkins
Major new architectural framework proposal
Revision 1.1  2001/11/16 23:21:38  spadkins
initial stuff
<h3>版本</h3>
原版  $Id: perlstyle.pod,v 1.2 2001/11/30 16:00:52 spadkins Exp $
中译版 $Id: perlstyle.pod,v 1.2 2005/05/02 13:00:52 spadkins Exp $
</pre>
</code></code></code></code></div>
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:11 <a href="http://www.cnitblog.com/ttyuren/articles/27185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>grep 函数介绍</title><link>http://www.cnitblog.com/ttyuren/articles/27184.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:10:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27184.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27184.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27184.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27184.html</trackback:ping><description><![CDATA[<div class=topbanner><img src="http://www.perlchina.org/images/logo/perlchina_org.gif"> </div>
<div id=Content>
<h1>grep 函数介绍</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/saladjonk/"><u><font color=#0000ff>saladjonk</font></u></a><br>出处：<a href="http://www.perlchina.org/"><u><font color=#810081>中国Perl协会</font></u></a> <a href="http://fund.perlchina.org/"><u><font color=#0000ff>FPC</font></u></a>(Foundation of Perlchina)<br>作者：Richard Anderson <br>原名：Perl :grep,map nad sort (grep 部分) <br>原文：http://xrl.us/gcqq <br>发表：2002 <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：53分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=53#文评"><u><font color=#0000ff>[查看文评]</font></u></a></p>
            <u><font color=#0000ff>
            <hr>
            </font></u></td>
        </tr>
    </tbody>
</table>
<p><u><font color=#0000ff></font></u></p>
<p><strong>grep函数</strong></p>
<p>(如果你是个Perl的新手,你可以先跳过下面的两段,直接到 Grep vs.loops 样例这一部分,放心,在后面你还会遇到它)<br>
<pre>&lt;pre&gt;
grep BLOCK LIST
grep EXPR, LIST
&lt;/pre&gt;</pre>
<br>grep 函数会用 <span class=caps>LIST </span>中的元素对 <span class=caps>BLOCK </span>或 EXPR 求值，而且会把局部变量 $_ 设置为当前所用的 <span class=caps>LIST </span>中的元素。BLOCK 块是一个或多个由花括号分隔开的Perl 语句，而 List 则是一有序列表。EXPR 是一个或多个变量，操作符，字符，函数，子程序调用的组成的表达式。Grep 会对 <span class=caps>BLOCK </span>块或 <span class=caps>EXPR </span>进行求值，将求值为%{color:red}真%的元素加入到 Grep 返回列表中。如果 <span class=caps>BLOCK </span>块由多个语句组成,那么 Grep 以 <span class=caps>BLOCK </span>中的最后一条语句的求值为准。LIST 可以是一个列表也可以是一个数组。在标量上下文中，grep 返回的是 <span class=caps>BLOCK </span>或 EXPR 求值为真的元素个数。
<p>&nbsp;</p>
<p>请避免在 <span class=caps>BLOCK </span>或 EXPR 块中修改 $_ ,因为这会相应的修改 <span class=caps>LIST </span>中元素的值。同时还要避免把 grep 返回的列表做为左值使用，因为这也会修改 <span class=caps>LIST </span>中的元素。(所谓左值变量就是一个在赋值表达式左边的变量)。一些 Perl hackers 可能会利用这个所谓的&#8221;特性&#8221;，但是我建议你不要使用这种混乱的编程风格.</p>
<p><strong>grep 与循环</strong></p>
<p>这个例子打印出 myfile 这个文件中含有 terriosm 和 nuclear 的行(大小写不敏感).<br>
<pre><code>
open FILE "&lt;myfile" or die "Can't open myfile: $!";
print grep /terrorism|nuclear/i, &lt;FILE&gt;;
</code></pre>
<br>对于文件很大的情况，这段代码耗费很多内存。因为 grep 把它的第二个参数作为一个列表上下文看待，所以 &lt; &gt; 操作符返回的是整个的文件。更有效的代码应该这样写:<br>
<pre><code>
while ($line = &lt;FILE&gt;) {
if ($line =~ /terrorism|nuclear/i) { print $line }
}</code></pre>
<br>通过上面可以看到，使用循环可以完成所有 grep 可以完成的工作。那为什么我们还要使用 grep 呢？一个直观的答案是 grep 的风格更像 Perl，而 loops（循环）则是 C 的风格。一个更好的答案是，首先, grep 很直观的告诉读者正在进行的操作是从一串值中选出想要的。其次，grep 比循环简洁。(用软件工程的说法就是 grep 比循环更具有内聚力)。基本上，如果你对 Perl 不是很熟悉,随便你使用循环。否则，你应该多使用像 grep 这样的强大工具.
<p>&nbsp;</p>
<p><strong>计算数组中匹配给定模式的元素个数</strong></p>
<p>在一个标量上下文中,grep 返回的是匹配的元素个数.</p>
<pre>$num_apple = grep /^apple$/i, @fruits;</pre>
<br>^ 和 $ 匹配符的联合使用指定了只匹配那些以 apple 开头且同时以 apple 结尾的元素。这里 grep 匹配 apple 但是 pineapple 就不匹配。
<p><strong>输出列表中的不同元素</strong></p>
<pre><code>@unique = grep { ++$count{$_} &lt; 2 }
qw(a b a c d d e f g f h h);
print "@unique\n";
输出结果: a b c d e f g h</code></pre>
<code>$count{$_}</code> 是 Perl 散列中的一个元素,是一个键值对 ( Perl中的散列和计算机科学中的哈希表有关系,但不完全相同) 这里 count 散列的键就是输入列表中的各个值,而各键对应的值就是该键是否使 <span class=caps>BLOCK </span>估值为真的次数。当一个值第一次出现的时候 <span class=caps>BLOCK </span>的值被估为真（因为小于2），当该值再次出现的时候就会被估计为假（因为等于或大于2）。
<p><strong>取出列表中出现两次的值</strong><br>
<pre><code>
@crops = qw(wheat corn barley rice corn soybean hay
alfalfa rice hay beets corn hay);
@duplicates = grep { $count{$_} == 2 }
grep { ++$count{$_} &gt; 1 } @crops;
print "@duplicates\n";</code></pre>
<br>在 grep 的第一个列表元素被传给 <span class=caps>BLOCK </span>或 EXPR 块前，第二个参数被当作列表上下文看待。这意味着，第二个 grep 将在左边的 grep 开始对 <span class=caps>BLOCK </span>进行估值之前完全读入 count 散列。
<p>&nbsp;</p>
<p><strong>列出当前目录中的文本文件</strong></p>
<pre><code>@files = grep { -f and -T } glob '* .*';
print "@files\n";</code></pre>
<br>glob 函数是独立于操作系统的,它像 Unix 的 shell 一样对文件的扩展名进行匹配。单个的 <code>*</code> 表示匹配所以当前目录下不以 <code>.</code> 开头的文件， <code>.*</code> 表示匹配当前目录下以 <code>.</code> 开头的所有文件。 -f 和 -T 文件测试符分别用来测试纯文件和文本文件，是的话则返回真。使用 -f and -T 进行测试比单用 -T 进行测试有效，因为如果一个文件没有通过 -f 测试，那么相比 -f 更耗时的 -T 测试就不会进行。
<p><strong>从数组中选出非重复元素</strong></p>
<pre><code>@array = qw(To be or not to be that is the question);
print "@array\n";
@found_words =
grep { $_ =~ /b|o/i and ++$counts{$_} &lt; 2; } @array;
print "@found_words\n";
输出结果:
To be or not to be that is the question
To be or not to question</code></pre>
<p>逻辑表达式 <code>$_ =~ /b|o/i</code> 匹配包含有 b 或 o 的元素(不区别大小写)。在这个例子里把匹配操作放在累加前比反过来做有效些。比如，如果左边的表达式是假的，那么右边的表达式子就不会被计算。</p>
<p><strong>选出二维坐标数组中横坐标大于纵坐标的元素</strong></p>
<pre><code># An array of references to anonymous arrays
@data_points = ( [ 5, 12 ], [ 20, -3 ],
[ 2, 2 ], [ 13, 20 ] );
@y_gt_x = grep { $_-&gt;[0] &lt; $_-&gt;[1] } @data_points;
foreach $xy (@y_gt_x) { print "$xy-&gt;[0], $xy-&gt;[1]\n" }
输出结果:
5, 12
13, 20</code></pre>
<p><strong>在一个简单数据库中查找餐馆</strong></p>
<p>这个例子里的数据库实现方法不是实际应用中该使用的，但是它说明了使用 grep 函数的时候，只要你的内存够用， <span class=caps>BLOCK </span>块的复杂度基本没有限制。<br>
<pre><code># @database is array of references to anonymous hashes
@database = (
{ name      =&gt; "Wild Ginger",
city      =&gt; "Seattle",
cuisine   =&gt; "Asian Thai Chinese Korean Japanese",
expense   =&gt; 4,
music     =&gt; "\0",
meals     =&gt; "lunch dinner",
view      =&gt; "\0",
smoking   =&gt; "\0",
parking   =&gt; "validated",
rating    =&gt; 4,
payment   =&gt; "MC VISA AMEX",
},
#   { ... },  etc.
);
sub findRestaurants {
my ($database, $query) = @_;
return grep {
$query-&gt;{city} ?
lc($query-&gt;{city}) eq lc($_-&gt;{city}) : 1
and $query-&gt;{cuisine} ?
$_-&gt;{cuisine} =~ /$query-&gt;{cuisine}/i : 1
and $query-&gt;{min_expense} ?
$_-&gt;{expense} &gt;= $query-&gt;{min_expense} : 1
and $query-&gt;{max_expense} ?
$_-&gt;{expense} &lt;= $query-&gt;{max_expense} : 1
and $query-&gt;{music} ? $_-&gt;{music} : 1
and $query-&gt;{music_type} ?
$_-&gt;{music} =~ /$query-&gt;{music_type}/i : 1
and $query-&gt;{meals} ?
$_-&gt;{meals} =~ /$query-&gt;{meals}/i : 1
and $query-&gt;{view} ? $_-&gt;{view} : 1
and $query-&gt;{smoking} ? $_-&gt;{smoking} : 1
and $query-&gt;{parking} ? $_-&gt;{parking} : 1
and $query-&gt;{min_rating} ?
$_-&gt;{rating} &gt;= $query-&gt;{min_rating} : 1
and $query-&gt;{max_rating} ?
$_-&gt;{rating} &lt;= $query-&gt;{max_rating} : 1
and $query-&gt;{payment} ?
$_-&gt;{payment} =~ /$query-&gt;{payment}/i : 1
} @$database;
}
%query = ( city =&gt; 'Seattle', cuisine =&gt; 'Asian|Thai' );
@restaurants = findRestaurants(\@database, \%query);
print "$restaurants[0]-&gt;{name}\n";
输出结果: Wild Ginger</code></pre>
<p>&nbsp;</p>
</div>
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:10 <a href="http://www.cnitblog.com/ttyuren/articles/27184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用 strict 和 warnings</title><link>http://www.cnitblog.com/ttyuren/articles/27183.html</link><dc:creator>ttyuren</dc:creator><author>ttyuren</author><pubDate>Fri, 18 May 2007 00:09:00 GMT</pubDate><guid>http://www.cnitblog.com/ttyuren/articles/27183.html</guid><wfw:comment>http://www.cnitblog.com/ttyuren/comments/27183.html</wfw:comment><comments>http://www.cnitblog.com/ttyuren/articles/27183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ttyuren/comments/commentRss/27183.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ttyuren/services/trackbacks/27183.html</trackback:ping><description><![CDATA[<div class=topbanner><img src="http://www.perlchina.org/images/logo/perlchina_org.gif"> </div>
<div id=Content>
<h1>如何使用 strict 和 warnings</h1>
<table class=author width="100%" border=0>
    <tbody>
        <tr>
            <td width="100%">译者/作者：<a href="http://wiki.perlchina.org/main/show/havel.zhang/"><u><font color=#0000ff>havel.zhang</font></u></a><br>出处：<a href="http://www.perlchina.org/"><u><font color=#810081>中国Perl协会</font></u></a> <a href="http://fund.perlchina.org/"><u><font color=#0000ff>FPC</font></u></a>(Foundation of Perlchina)<br>原 名：Use Strict And Warnings <br>中 文: 如何使用 strict 和 warnings <br>作 者：runiq <br>原 文：http://www.perlmonks.org/?node_id=111088 <br>发 表：Sep 07, 2001 <br>翻 译：havel.zhang <br>审 校：qiang <br>请保护作者的著作权,维护作者劳动的结晶。
            <p>得分：69分 <a href="http://www.perlchina.org/archive/archive.php?action=archive&amp;page=32#文评"><u><font color=#0000ff>[查看文评]</font></u></a></p>
            <u><font color=#0000ff>
            <hr>
            </font></u></td>
        </tr>
    </tbody>
</table>
<p><u><font color=#0000ff></font></u></p>
<h3>什么场合要用 use strict</h3>
<p>当你的程序有一定的行数时，尤其是在一页放不下时，或者是你找不到发生错误的原因时。 </p>
<h3>为什么要用 use strict？</h3>
<p>众多的原因之一是帮你寻找因为错误拼写造成的错误。比如错误使用了'$recieve_date' 变量，但实际上你在程序中已声明的是 '$receive_date' 变量，这个错误就很难发现。同样，use strict 迫使你把变量的范围缩到最小，使你不必担心同名变量在程序的其它部份发生不良作用。（尽管这是 my 的功能，但是如果你使用 use strict 的话，它会强迫你用 my 声明变量，来达到上述目的）。用 use strict 麻烦吗？不麻烦，只要在你的脚本的开始加上11个字符而已！(use strict;), 另外在整个程序中用my 声明变量。不错，那我怎么用 use strict 呢？在你的脚本的开头 '#!/usr/local/bin/perl' 后面加上这句就行。 </p>
<pre><code>use strict;
</pre>
</code><font face=宋体>得，程序出错了，我该怎么办？常见的错误信息一般如下： </font>
<pre><code>Global symbol "$xxx" requires explicit package name at ./tst line 5.
</pre>
</code><font face=宋体>这是我们要马上解决的错误。（如果出现类似于 'Server Error' 之类的错误，请检查一下你的 web 服务器上的 error logs， 或用 </font><a href="http://search.cpan.org/search?mode=module&amp;query=CGI::Carp"><font color=#0000ff><font face=宋体><u>"CGI::Carp"</u><span style="TEXT-DECORATION: none"> </span></font></font></a><font face=宋体>包。 ）任何时候，当你要声明一个变量时，都要把 'my' 放在前面。例如： </font>
<pre><code># 把这段代码:
$string = "hello world";
@array = qw(ABC DEF);
%hash = (A=&gt;1, B=&gt;2);
# 改成:
my $string = "hello world";
my @array = qw(ABC DEF);
my %hash = (A=&gt;1, B=&gt;2);
# 把这段代码:
# '$name' is global here
foreach $name (@names) {
print "Name: $name\n";
}
# 改成:
foreach my $name (@names) {
# Now '$name' only exists in this block
print "Name: $name\n";
}
# 把这段代码:
# 同样, '$digit' 在这里是全局变量
foreach $digit (@digits) {
$number = 10*$number + $digit;
}
print "Number: $number\n";
# 改成： (外层的变量('$number')
# 将在外层声明):
my $number = 0;
foreach my $digit (@digits)
# 现在'$digit' 仅仅在这个代码块里存在
$number = 10*$number + $digit;
}
print "Number: $number\n";
# 把这段代码:
sub my_sub {
($arg1, $arg2) = @_;
print "Arg1: $arg1 Arg2: $arg2\n";
}
# 改成:
sub my_sub {
my ($arg1, $arg2) = @_;
print "Arg1: $arg1 Arg2: $arg2\n";
}
# 下面的代码好像在用 DBI 嘛？一样要改！:
$sth-&gt;bind_columns(\$field1, \$field2);
while ($sth-&gt;fetch) {
print "F1: $field1 F2: $field2\n";
}
# 改成:
$sth-&gt;bind_columns(\my ($field1, $field2));
while ($sth-&gt;fetch) {
print "F1: $field1 F2: $field2\n";
}
</pre>
</code><font face=宋体>这也太麻烦了吧。懒惰不是 Perl 文化中的美德吗？当然，懒惰是我们的美德。因为你会发现使用 use strict 之后，我们就不必花太多的时间自己去查找 use strict 可以找到的很多简单错误。那 warnings 又是什么？ 哦，对了。在 Perl 5.6 及以后的版本里，我们可以在写 'use strict;' 的位置旁写 'use warnings;': </font>
<pre><code>use warnings;</pre>
</code><font face=宋体>在 Perl 5.6 版之前（或者为了不同 Perl 版本间的兼容 ），你可以用命令行参数 '#!/usr/bin/perl -w'。还有一种办法是设置$^W变量（不过，如果$^W不在BEGIN{}程序块里的话，就没办法截取编译时的错误提示，所以一般我们用 '-w'）: </font>
<pre><code>#!/usr/local/bin/perl -w
# 或者
$^W = 1;
# 或者
BEGIN { $^W = 1 }</pre>
</code><font face=宋体>如果你确定不用 warnings，你可以限制它的使用范围，如： </font>
<pre><code># 把这段代码:
sub add_two_numbers_which_might_be_undef {
$_[0] + $_[1];
}
# 根据Perl 的版本不同改成下面的样子:
# 1
sub add_two_numbers_which_might_be_undef {
# 参见 'perldoc perllexwarn'
# 因为最好是只在你希望的地方禁止掉warning
no warnings "uninitialized";
$_[0] + $_[1];
}
# 2
sub add_two_numbers_which_might_be_undef {
local $^W;
$_[0] + $_[1];
}</pre>
</code><font face=宋体>或者，你应像前面例子中声明 '$number'一样初始化变量。 </font>
<p>你还可以参阅 <a href="http://www.perlmonks.org/?node=Ovid"><u><font color=#0000ff>"Ovid的"</font></u></a>: 妙文"'use strict' is not Perl" 。"okay，现在你应该没什么借口不用 use strict 或 use warnings 了吧，它使我们大家生活可以轻松一些：）</p>
</div>
<img src ="http://www.cnitblog.com/ttyuren/aggbug/27183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ttyuren/" target="_blank">ttyuren</a> 2007-05-18 08:09 <a href="http://www.cnitblog.com/ttyuren/articles/27183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>