Perl中捕获警告信息、异常信息并写入日志详解

2019-10-01 09:50:01丽君

我们也把__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);
  };