防止Perl打印相同的警告消息
以以下无意义脚本为例:防止Perl打印相同的警告消息,perl,warnings,Perl,Warnings,以以下无意义脚本为例: use strict; use warnings; my $uninitialisedValue; while(<>){ print ${$uninitialisedValue}{$_},"\n"; } 使用严格; 使用警告; 我的$UninitializedValue; while(){ 打印${$uninitialisedValue}{$},“\n”; } 它从命令行运行: $ perl warningPrinter.pl
use strict;
use warnings;
my $uninitialisedValue;
while(<>){
print ${$uninitialisedValue}{$_},"\n";
}
使用严格;
使用警告;
我的$UninitializedValue;
while(){
打印${$uninitialisedValue}{$},“\n”;
}
它从命令行运行:
$ perl warningPrinter.pl < longfile.txt
$perl warningPrinter.pl
无论标准输入包含什么,标准输出都将充满:
Use of uninitialized value in print at warningPrinter.pl line 16, <> line 1.
Use of uninitialized value in print at warningPrinter.pl line 16, <> line 2.
Use of uninitialized value in print at warningPrinter.pl line 16, <> line 3.
Use of uninitialized value in print at warningPrinter.pl line 16, <> line 4.
...
在warningPrinter.pl第16行第1行的打印中使用未初始化值。
在warningPrinter.pl第16行第2行的打印中使用未初始化值。
在warningPrinter.pl第16行第3行的打印中使用未初始化值。
在warningPrinter.pl第16行第4行的打印中使用未初始化值。
...
我处理很长的文件,所以在测试脚本时将其作为输出接收至少有点恼人。该过程可能需要一段时间才能响应Ctrl+C终止信号,而我的终端突然充满了相同的错误消息
有没有办法让Perl只打印相同且重复出现的警告消息的第一个实例,或者让警告消息对脚本的执行造成致命影响?鉴于我从未制作过一个脚本,尽管里面有警告,但它仍然有效,我也会接受。但如果我能让Perl只打印一次相同的警告,可能会更方便。我想我会向您展示如何创建独特的警告逻辑。但我不推荐:
my %printed;
local $SIG{__WARN__} = sub {
my $message = shift;
my ( $msg, $loc ) = $message =~ m/(.*?) at (.*?line \d+)/;
print $message unless $printed{$loc}{$msg}++;
};
我应该说,我不建议将此作为一般做法。因为最好有一个警告政策。这是一个可以接受未定义值的操作,或者您不希望处理undef
值。我尝试从已完成的代码中删除所有警告
在第一种情况下,将无警告设置为“未初始化”在for
循环中的code>是一件容易得多的事情,也是一件常规的事情。在第二种情况下,你可能想失败
但是,如果您确实希望处理但警告一次,比如您希望对数据进行可靠的处理,但希望警告上游流程您得到了一些坏数据,那么您可以创建一个子警告\u once
:
{ use Carp ();
my %warned;
sub warn_once {
my $message = shift;
my ( $msg, $loc ) = $message =~ m/(.*?) at (.*?line \d+)/;
Carp::carp( $message ) unless $warned{$loc}{$msg}++;
};
}
这样称呼它:
while ( <> ) {
warn_once( '$uninitialisedValue is uninitialized' )
unless defined( $uninitialisedValue)
;
no warnings 'uninitialized';
print ${$uninitialisedValue}{$_},"\n";
}
while(){
警告_一次(“$UninitializedValue未初始化”)
除非定义($uninitialisedValue)
;
没有“未初始化”的警告;
打印${$uninitialisedValue}{$},“\n”;
}
那你已经决定了 尝试另一篇StackOverflow帖子:[如果生成警告,我如何使Perl死亡?][1][1]:非常好use warnings FATAL=>'all'
在我的例子中,在警告后终止进程非常有效。在读取文件时,尤其是当该文件较大时,不要使用for
,因为for循环会将其列表预加载到内存中。使用代替。另外,将文件重定向到stdin是多余的,只需将该文件用作参数即可。在您的特定问题中,重新打开文件的STDERR可能是一个解决方案。然而,我发现从STDIN读取代码更快,并且脚本将自动与另一个进程的管道兼容。如果我只是从命令行获取一个参数,那么我必须检查用户是否真的想从STDIN读取数据。@kikumbob菱形运算符同时处理STDIN或文件参数。你的区别是无效的。在使用菱形操作符时,使用script.pl
和script.pl对于实际目的是相同的。很好!我想我必须将这种东西添加到我想使用这种逻辑的每个脚本中?你为什么不推荐它?@kikumbob我将在我的帖子中详细说明。请注意,诊断
模块完成了所有这一切,除了关于考虑输入块的行号的部分。