分类: LINUX
2011-07-14 10:18:34
简洁愉快的say(实用性:3星)
say "Hello, world";
等同于
print "Hello, world\n";
自动添加换行符,也许很不起眼的一个新函数,但是减少了按键次数。
直观的正则表达式命名捕捉(实用性:3星半)
以往,我们使用perl的内置变量$1,$2...来记录正则表达式的匹配内容,e.g.
如果变量在后续部分还要使用,会使程序易读性下降;重新赋值于新变量又使得程序无端多了两行;于是,懒惰的程序员可以使用命名捕捉了:
所以可以看出,?
同样,对于反向引用\1,\2,同样可以采用命名捕捉方式,例如,可以把以下代码
更替为
即用\g{name}代替\2咯,也可以用\k
这一点,在反向引用数目过多,数不清括号来的时候便颇为好用了:)
新增的短路操作符:定义否// (实用性:4星)
恩,我们知道,善用短路操作符&&(即 and)、||(即or)会使得程序简洁而直观,比较常见的是打开文件句柄的例子:
open INPUT, "<", "$ARGV[0]" || die "Cannot open file: $!";
即当||的左边为真(打开文件成功)时,右边短路不会报错。5.10版的Perl新添了定义否的短路操作符//。它有什么功效呢?看看这个例子:
这个代码里,我们想在哈希表里检索微阵列的gene对应的信号,如果检索的gene在哈希表里不存在,就是这块芯片不含该基因的探针,我们将信号值定为缺失值NaN,便于下一步用R处理。但这里有个问题,就是当gene对应的信号值为0的时候,||左边的表达式为假,$signal将会定义为缺失值,这显然不是我们的本意,解决办法是采用定义否操作符//:当只有//左边的表达式为undef时,才使用右边的值。
非常智能的智能匹配(实用性: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显然更加强大。
有细心的人会注意到:我们没有添加和switch语句配套的break,当表达式为真时不会跳出而会一直往下落(俗称fall-through)。事实上,和switch颇为不同的是,switch是默认fall-through,而Perl中的given-when默认是当表达式为真时执行语句,然后跳出控制块!对,所以以上的程序并没有错,如果要实现fall-through,需要添加continue控制符。
奇妙的是,如果判断对象不是标量,而是数组,或者是哈希展开的键值(总而言之,是列表即可),直接用foreach替代given可以达到遍历整个列表的效果:
是的,我们还可以在when语句之间添加其他的语句,不错吧^ - ^