Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止Perl打印相同的警告消息_Perl_Warnings - Fatal编程技术网

防止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我将在我的帖子中详细说明。请注意,
诊断
模块完成了所有这一切,除了关于考虑输入块的行号的部分。