Perl高级技巧

切片

切片常常是从列表中读取少量数据的最简单方法。列表切片时,列表一定要用圆括号括起来,切片的下标是任意的,并且可重复。

my ($first ,$last) = (sort @names)[0,-1];
my ($first ,$last) = (@names)[0,1,3,1,0];

对于数组切片来说,可以省略括号,在数组变量后面直接接上方括号就可以了。

@items[2,3] = ($new_address,$new_home_phone);

hash切片

和数组切片类似,我们也可以用hash切片从哈希里切出一些元素。

my @three_scores = @score{qw/ barney fred dino/};

my @players = qw /barney fred dino/;
my @bowling_scores = (195,205,30);
@score{@players} = @bowling_scores;

这里有人可能要问,为什么提到hash没有使用%,因为百分号代表整个hash,而哈希切片一定是列表而不是哈希。

捕获错误eval

eval是一个表达式,这点跟while或foreach不同,当eval发现在它监察范围内出现致命错误时,会立即停止运行整个块,退出后继续运行其余代码,这样就不会使你的程序过早结束。监察语句块末尾有分号。

eval {$barney = $fred / $dino};
my $barney = eval {$fred / $dino} // 'Not a number';
print "I can not divide by $dino : $@" if $@;

eval的返回值是语句块最后一条表达式的执行结果,这点跟子程序相同,因此我们可以把eval当成赋值语句使用。如果语句块发生了错误,evel会返回undef,并在特殊变量\$@里设置错误信息。

我们常常会用到其他人写的子程序,对于内部细节完全没有概念,但又不想因为它而导致程序崩溃,有些人故意使用die抛出错误信息,以为他们期待外部使用者通过eval捕获错误并作适当处理。

autodie

perl自带autodie编译指令,它负责自动抛出异常,而不需要我们手动的在每一个可能出错的地方手动die.autodie抛出异常时,会把一个autodie::exception对象放带$@里。我们可以通过这个对象提取捕获的错误类型。

use autodie;
open my $fh,'>',$file_name;
given($@){
    when(undef){say "no error";}
    when('open'){say "error from open";}
    when(':io'){say "non-open IO error";}
    default {say "not an autodie error at all";}
    }

grep筛选列表

有时候你希望选出列表的满足某些条件的部分成员。在grep运行时,\$_会轮流成为列表中每个元素的别名,因此在grep表达式中修改\$_的内容通常不是一个好主意,因为会破坏原始数据。

my @odd_numbers = grep {$_ % 2} 1..1000;
my @matching_lines = grep /\bfred\b/i,<$fh>;

如果选择器需要的只是一个简单的表达式,而不是整个代码块,那么只要在这个表达式后面用逗号结束就可以了。在标量上下文中,grep返回的是满足条件的元素个数。

map把列表元素变形

map与grep非常相似,只不过它返回的不是逻辑真假值,而是该表达式的实际计算结果,最终返回一系列这样的结果组成的列表.

my @formatted_data = map {&big_money($_)} @data;
print"some powers of 2 are : \n",
    map "\t".(2**$_)."\n",1..15;

Comments !