Chinaunix首页 | 论坛 | 博客
  • 博客访问: 599915
  • 博文数量: 60
  • 博客积分: 3993
  • 博客等级: 中校
  • 技术积分: 1572
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-08 17:08
文章分类

全部博文(60)

文章存档

2012年(7)

2011年(35)

2010年(8)

2009年(7)

2008年(3)

分类: LINUX

2011-07-14 10:18:34


Perl 5.10的新特性

简洁愉快的say(实用性:3星)

say "Hello, world";

等同于

print "Hello, world\n";

自动添加换行符,也许很不起眼的一个新函数,但是减少了按键次数。

 

直观的正则表达式命名捕捉(实用性:3星半)

以往,我们使用perl的内置变量$1,$2...来记录正则表达式的匹配内容,e.g.

my $line = "Symbol:AGO1 Chromosome:2R";
if($line =~ /Symbol:(\w+)\s*Chromosome:(\w+)/) {
say "Gene $1 is on chromosome $2!";
}

如果变量在后续部分还要使用,会使程序易读性下降;重新赋值于新变量又使得程序无端多了两行;于是,懒惰的程序员可以使用命名捕捉了:

my $line = "Symbol:AGO1 Chromosome:2R";
if($line =~ /Symbol:(?\w+)\s*Chromosome:(?\w+)/) {
say "Gene $+{gene} is on chromosome $+{chr}!";
}

所以可以看出,?的捕捉方式,实际上是把括号内匹配的内容存储在%+这样一个奇怪的哈希里了。所以要调用捕捉的内容,用$+{name}即可了!虽然看起来很诡异,但是在大的程序块里会相当好用噢。

同样,对于反向引用\1,\2,同样可以采用命名捕捉方式,例如,可以把以下代码

my $line = "Symbol:AGO1 Chromosome:2R Location:2R:9,834,047..9,845,594";
if($line =~ /Symbol:(\w+)\s*Chromosome:(\w+).*(\2:[.,\d]+))/ {
say "The location of Gene $1 is $3!";
}

更替为

my $line = "Symbol:AGO1 Chromosome:2R Location:2R:9,834,047..9,845,594";
if($line =~ /Symbol:(\w+)\s*Chromosome:(?\w+).*(\g{chr}:[.,\d]+))/ {
say "The location of Gene $1 is $3!";
}

即用\g{name}代替\2咯,也可以用\k等效代替

my $line = "Symbol:AGO1 Chromosome:2R Location:2R:9,834,047..9,845,594";
if($line =~ /Symbol:(\w+)\s*Chromosome:(?\w+).*(\k:[.,\d]+))/ {
say "The location of Gene $1 is $3!";
}

这一点,在反向引用数目过多,数不清括号来的时候便颇为好用了:)

 

新增的短路操作符:定义否// (实用性:4星)

恩,我们知道,善用短路操作符&&(即 and)、||(即or)会使得程序简洁而直观,比较常见的是打开文件句柄的例子:

open INPUT, "<", "$ARGV[0]" || die "Cannot open file: $!";

即当||的左边为真(打开文件成功)时,右边短路不会报错。5.10版的Perl新添了定义否的短路操作符//。它有什么功效呢?看看这个例子:

my $signal = $gene_signal{$gene} || "NaN";
say "$gene\t$signal"; #当$gene_signal{$gene}等于0时,会输出NaN

这个代码里,我们想在哈希表里检索微阵列的gene对应的信号,如果检索的gene在哈希表里不存在,就是这块芯片不含该基因的探针,我们将信号值定为缺失值NaN,便于下一步用R处理。但这里有个问题,就是当gene对应的信号值为0的时候,||左边的表达式为假,$signal将会定义为缺失值,这显然不是我们的本意,解决办法是采用定义否操作符//:当只有//左边的表达式为undef时,才使用右边的值。

my $signal = $gene_signal{$gene} || "NaN";
say "$gene\t$signal"; #当$gene_signal{$gene}等于0时,会输出0

 

非常智能的智能匹配(实用性:5星)

我想善解人意是Perl的一个非常重要的哲学思想,智能匹配是很好的体现;一旦学会,你会很快在新写的程序用到它。

简单的说,智能匹配操作符(~~)能根据两端的数据类型进行比较,一个一目了然的例子是:

say "The two gene groups are the same!" if @gene1 ~~ @gene2;

没错,它能快速比较两个数组是否相同(当然,数组元素的顺序也要考虑);它的功能远不止如此,基本标量,数组,哈希,甚至匹配模式,任意两两组合,它就能进行你想要的(一般情况下)的智能匹配,另外一个神奇的例子是

say "Yes, miR-310 is a newly evolved miRNA!" if %new_miR_target ~~ /miR(-?)310/i;

猜到了吧,这段代码会在%new_miR_target的key中检索/miR(-?)310/i这个pattern,如果有符合的对象便say yes。事实上,一张较完整的~~功能表如下(摘录自Learning Perl, 5ed, p224)

事实上熟悉了它看起来复杂的规则,你一定会爱上它。

 

类switch控制结构:given-when(实用性:4星半)

我想每一个C程序员都会抱怨Perl为什么没有switch这样的控制结构,而不得不选择繁杂的多层if...elsif..elsif.....else。事实上,give-when就是一个新版升级的switch。基于智能匹配的表达式,given-when显然更加强大。

given($flybase_id) {
when(/^fbgn/i) {say "It's a gene!"}
when(/^fbtr/i) {say "It's a transcript!"}
when(/^fbpp/i) {say "It's a polypeptide!"}
default {say "I've no idea what it is."}
}

有细心的人会注意到:我们没有添加和switch语句配套的break,当表达式为真时不会跳出而会一直往下落(俗称fall-through)。事实上,和switch颇为不同的是,switch是默认fall-through,而Perl中的given-when默认是当表达式为真时执行语句,然后跳出控制块!对,所以以上的程序并没有错,如果要实现fall-through,需要添加continue控制符。

given($flybase_id) {
when(!/^fbgn/i) {say "It's not a gene!"; continue}
when(!/^fbtr/i) {say "It's not a transcript!"; continue}
when(!/^fbpp/i) {say "It's not a polypeptides!"; continue}
default {say "I've no idea what it is."} #多么不自然的一个例子啊
}

奇妙的是,如果判断对象不是标量,而是数组,或者是哈希展开的键值(总而言之,是列表即可),直接用foreach替代given可以达到遍历整个列表的效果:

foreach (@flybase_id) {
when(/^fbgn/i) {say "It's a gene!"}
when(/^fbtr/i) {say "It's a transcript!"}
when(/^fbpp/i) {say "It's a polypeptide!"}
say "Moving to default...";
default {say "I've no idea what it is."}
}

是的,我们还可以在when语句之间添加其他的语句,不错吧^ - ^

 

Perl 5.12的新特性包括:
  • 更好的支持Unicode标准;
  • 解决Y2038问题,正确支持2038年后的时间;
  • 当用户使用过时功能时Perl会发出警告;
  • 新的试验性API,允许开发者用“可置换性(pluggable)”关键字和语法扩展Perl;

Perl 5.14的新特性包括:

  • 支持Unicode 6.0 ,改进了诸多与Unicode相关的性能
  • 更好的支持IPv6
  • 极大简化了CPAN客户端的自动配置
  • 新的/r 标记使得s///无损替换
  • 新的正则表达式标记来控制被匹配的字符串是否应被视为ASCII 或者Unicode。
  • 新的"package Foo { }"语法
  • 较以往版本,占用更少的内存和CPU
阅读(1934) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

cinanine2011-07-24 15:15:35

简洁愉快