清纯自然

2010/09/13

初品BioPerl(序:让程序读起来更生动)

Filed under: Perl — billzt @ 9:38 下午

苏姐姐:或许在接触BioPerl之前你可能已听说过这个词,但却不明白它是做什么用的。其实,它的用途很简单:让我们的Perl程序读起来更生动一点儿,好听一点儿,易懂一点儿。没错,哪怕你不用BioPerl,同样可以完成相同的任务!而且可能执行的速度更快!但是这样一来,虽然便宜了机器,却苦了我们自己呵! 😦
      闲话休提,言归正传。我们来看一个“小驼书”中的例子(强烈建议你在学习BioPerl之前至少把小驼书啃十遍。BioPerl属于高级课题,若根基不稳,学起来是很痛苦嘀!)。
      在变量$name中存放了一个文件路径名,请取出它的文件基名(basename)和目录名(dirname),再把它们重新连接成完整的文件名(咋一看这个操作很无聊,没关系,这只是个例子而已)。我们应该会写出这样的代码:
      my
$name=“/usr/local/bin/perl”;

      (my $basename=$name)=~s%.*/%%;             # 取出文件基名$basename
      (my $dirname=$name)=~s%(.*)/.*$%$1%;       # 取出目录名$dirname
      my $filename=“$dirname/$basename”;         # 将文件基名和目录名连接起来

      说实话,除非你是一等一的高手,否则没有人能一眼就看出来诸如s%.*/%%这样的代码究竟是干什么用的,除非你在旁边加上了详尽的注释,而且你的变量名称取得很有意义(好的Perl程序员一定会这么做)。而且你如果仔细读过小驼书,应该知道上面这段代码不仅难懂晦涩,而且还有BUG。事实上,文件名中是可以包含换行符\n的,所以,正确的写法应该是s%.*/%%ss%(.*)/.*$%$1%s。不用说,这样一来就更难看啦!
      好吧,下面我们换用模块试试:
     use File::Basename;

     use File::Spec;
     my $name=“/usr/local/bin/perl”;
     my $basename = basename $name;
     my $dirname = dirname $name;          #现在是动听的名字basename和dirname,而非枯燥的s%.*/%%
     my $filename = File::Spec->catfile($dirname,$basename);
      现在的代码看起来“好看”多了,我们几乎不用添加额外的注释,就能看出来第四、五、六行代码是干什么的。
      当然,这样的“好看”是有代价的。
      首先,你的“记忆力”要足够好。例如开头的use两句,你不能写成use Files::Basename或者use File::basename或者use Basename,那样程序在运行时会报错“找不到文件”,(别忘了虽然正则表达式可以模糊匹配,use语句的文件查找好像还做不到这一点),你只有精确地写出use File::Basename才行。此外,最后一句也不能写成my $filename = catfile($dirname,$basename); ,必须使用“全名”的方式来调用对象的方法才行。(由于“小驼书”中不提对象,而BioPerl中有N多的面向对象的模块。所以初学者会对 -> 这样的符号很困惑,请多看几眼哦!)不过,这里所谓的“记忆力”其实在学习一般的Perl编程也是用到的。你既然知道应该拼写成elsif而不是elseif,那么记忆像basename,dirname这样的函数名完全不会太困难!如果实在不想花时间记的话,就查阅文档吧!可惜大部分文档是英文的,若你恰恰英文水平不好的话,就麻烦了。
      其次,程序加载额外的模块肯定要多费时间。如果程序只有几行(就像上面的例子那样),多费的时间应该不到1毫秒(我自己猜的,没有严格验证过哦);但如果普通的程序要运行好几个礼拜的话(一般都是有大量的循环),那把它改成用模块编写的(偏偏不巧模块加载就在循环里面),虽然程序变得“好看”了,但却要多花费好几个小时来运行(我有亲身体会!)。
      不过,话又说回来,程序运行慢,累的是机器;程序写得困难,累的是人。究竟你想累机器还是累人?应该具体情况具体分析!
      最后,为以后要写的BioPerl说几句:
     (1)我假设你已经熟读了小驼书,熟练地掌握了里面的所有内容。(很重要!Very Important!
     (2)你不需要看过羊驼书,哪怕你不了解“引用”和“对象”都没关系(其实我也不是很了解)。别忘了我们只是使用BioPerl模块,并不是去深究里面的细节。尽管大部分BioPerl模块都是面向对象的,没关系,尽管用吧!
     (3)我们只强调“使用”,或许你希望能够修改模块的源代码以更适合自己的风格,但别人会误解的,会认为你是在错误地使用模块!
     (4)我只写自己比较了解,亲身体验过的内容。要全面了解BioPerl,请查看它的官方教程http://www.bioperl.org/wiki/HOWTOs

在WordPress.com的博客.