我们也把__WARN__的处理函数替换成一个稍微复杂的版本:
my %WARNS;
local $SIG{__WARN__} = sub {
my $message = shift;
return if $WARNS{$message}++;
logger('warning', $message);
};
在调用logger之前,会检查一下当前字符串是否已经在%WARNShash表中。如果没有的话,会添加它并调用logger()。如果已经有了,就调用return,并不二次记录同样的事件。
你可能回忆起我们在unique values in an array也使用了同样的点子。
local是什么?
在上面所有的例子中,我使用local函数來局部化(警告处理)效果。严格来说,在这些例子中我们没有必要这么做,因为假设这些代码是主脚本的第一部分。这种情况下就无所谓了,毕竟是在全局作用域里面。
然而,最好是这么用。
local对于在模块中限制(对警告)的改变是很重要的。特别是要发布的模块。如果没有局部化,会影响整个应用程序。limit则会把影响限制在所在的闭合代码块里。
避免使用全局的%WARNS
如果你正在使用Perl 5.10或者更新的版本,你可以改写一下代码来替换掉全局变量%WARNS。要这么做的话,需在脚本的开头使用use v5.10;,然后在匿名函数内部使用state关键词来声明变量。
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
local $SIG{__WARN__} = sub {
state %WARNS;
my $message = shift;
return if $WARNS{$message}++;
logger('warning', $message);
};









