perl帮助使用perl模块排除错误消息

perl帮助使用perl模块排除错误消息,perl,Perl,我正在使用论坛上的这个工具测试perl脚本。我获取了样本数据并将其放在一个单独的文件中,然后使用open以这种方式进行尝试 我不明白为什么我会变得不自信。我得到消息: 在。/h.pl第15行第4行的联接或字符串中使用未初始化的值 #!/usr/local/bin/perl use warnings; use strict; use Data::Dumper; use Text::CSV_XS; open my $fh, '<', 't.out' or die "Unable t

我正在使用论坛上的这个工具测试perl脚本。我获取了样本数据并将其放在一个单独的文件中,然后使用open以这种方式进行尝试

我不明白为什么我会变得不自信。我得到消息:

在。/h.pl第15行第4行的联接或字符串中使用未初始化的值

#!/usr/local/bin/perl

use warnings;
use strict;
use Data::Dumper;
use Text::CSV_XS;

    open my $fh, '<', 't.out' or die "Unable to open: $!";
    my $csv = Text::CSV_XS->new( { sep_char => "\t" } );
    my @list;
    $csv->column_names ($csv->getline ($fh));
    while ( my $hr = $csv->getline_hr($fh) ) {
        push @list, $hr->{'Ball'};
    }

    print "@list\n";
    print Dumper(\@list);
结果:

$VAR1 = [
          undef,
          undef,
          undef
        ];
如果
$csv->getline\u hr($fh)
返回一个未定义的值,如果您试图打印列表
@list
,您将收到警告“
在连接或字符串中使用未初始化的值…”

您可以用一个简单的程序显式地测试这一点:

use strict;
use warnings;
my @list;
my $x = undef; # This is similar to what may happen in your program on the `push @list, @hr->{'Name'}` line
push @list, $x;
print "@list\n";
此外,如果您只是在进行调试,您可能希望
使用Data::Dumper
,然后
打印Dumper(\@list)
,因为您不会收到任何警告,并且您将更清楚地了解数据结构中存储的内容。

如果
$csv->getline\u hr($fh)
返回未定义的值,您将收到警告“
在连接或字符串中使用未初始化的值,…
”如果您试图打印列表
@list

您可以用一个简单的程序显式地测试这一点:

use strict;
use warnings;
my @list;
my $x = undef; # This is similar to what may happen in your program on the `push @list, @hr->{'Name'}` line
push @list, $x;
print "@list\n";

另外,如果您只是在调试,您可能希望
使用Data::Dumper
,然后
打印Dumper(\@list)
,因为您不会收到任何警告,而且您将更清楚地了解数据结构中存储的内容。

您的
@list
数组似乎未定义。请尝试检查:

if (scalar @list) {
    print "@list\n";
}

如果while循环从未执行过,
scalar@list
将返回
0
,因为数组为空。

您的
@list
数组似乎未定义。请尝试检查它:

if (scalar @list) {
    print "@list\n";
}

如果您的while循环从未执行过,
scalar@list
将返回
0
,因为数组是空的。

如其他人所述,
@list
很可能从未在其中获得值。如果
$csv->getline\u hr($fh)
第一次通过返回一个undef,您将永远不会将任何内容推入
@列表

您可以做两件事:

  • 您可以在打印前测试
    @list
    是否未初始化
  • 您可以松开
    use warnings
    pragma以不包括未初始化的警告:
  • 以下是您如何进行测试的方法:

    if (@list) {
       print "List = " . @list . "\n";
    } 
    else {
       print "List has no values\n";
    }
    
    如图所示,您可以使用
    scalar@list
    ,但在这种情况下这并不是必需的,我认为简单的
    if(@list)
    更清晰。您也可以使用
    if(defined@list)
    ,它非常清晰,但在过去几年中一直不受欢迎

    如果这是一个临时的(只是看看你的代码是否有效),你可以放松使用严格的:

    no warnings qw(uninitialized);
    print "@list\n";   #Now you won't get a warning if @list has no value
    use warnings;      #Turn the warnings back on. It helps you code better
    
    警告:在这种情况下,您的语句不会打印任何内容,这可能会让您更加困惑。请始终发出某种提示,以确保打印出某些内容:

    print "\@list = @list\n";
    
    当我打印出许多调试语句(稍后将删除这些语句)时,我更喜欢将其作为临时解决方案。事实上,我将为这些类型的消息创建一个特殊的
    debug
    子例程:

    use strict;
    use warnings;
    use constant DEBUG_LEVEL => 1;  #0 = no debug messages 1 = debug messages
    
    [...]
    while (yadda, yadda, yadda) {
       push @list, $hr->{Name};
    }
    debug (qq(\@list = ") . join "|", @list . qq("));
    
    [...]
    
    sub debug {
       my $message = shift;
    
       return if (not DEBUG_LEVEL);
       no warnings qw(uninitialized);
       print qq(DEBUG: $message\n);
       use warnings;      #Not really needed since the code block ends
       return $message;
    }
    

    正如其他人所提到的,很可能
    @list
    中从未包含值。如果
    $csv->getline\u hr($fh)
    第一次返回一个undef,您将永远不会将任何内容推入
    @list

    您可以做两件事:

  • 您可以在打印前测试
    @list
    是否未初始化
  • 您可以松开
    use warnings
    pragma以不包括未初始化的警告:
  • 以下是您如何进行测试的方法:

    if (@list) {
       print "List = " . @list . "\n";
    } 
    else {
       print "List has no values\n";
    }
    
    如图所示,您可以使用
    scalar@list
    ,但在这种情况下这并不是必需的,我认为简单的
    if(@list)
    更清晰。您也可以使用
    if(defined@list)
    ,它非常清晰,但在过去几年中一直不受欢迎

    如果这是一个临时的(只是看看你的代码是否有效),你可以放松使用严格的:

    no warnings qw(uninitialized);
    print "@list\n";   #Now you won't get a warning if @list has no value
    use warnings;      #Turn the warnings back on. It helps you code better
    
    警告:在这种情况下,您的语句不会打印任何内容,这可能会让您更加困惑。请始终发出某种提示,以确保打印出某些内容:

    print "\@list = @list\n";
    
    当我打印出许多调试语句(稍后将删除这些语句)时,我更喜欢将其作为临时解决方案。事实上,我将为这些类型的消息创建一个特殊的
    debug
    子例程:

    use strict;
    use warnings;
    use constant DEBUG_LEVEL => 1;  #0 = no debug messages 1 = debug messages
    
    [...]
    while (yadda, yadda, yadda) {
       push @list, $hr->{Name};
    }
    debug (qq(\@list = ") . join "|", @list . qq("));
    
    [...]
    
    sub debug {
       my $message = shift;
    
       return if (not DEBUG_LEVEL);
       no warnings qw(uninitialized);
       print qq(DEBUG: $message\n);
       use warnings;      #Not really needed since the code block ends
       return $message;
    }
    

    在你提到的问题中,我在最后一行也写了这句话:

    ETA:如果你要剪切粘贴来尝试,请确保 制表符在数据中结转

    您是否确保您的选项卡在复制/粘贴到您的文件
    't.out'
    后仍然有效

    这个模块对数据文件中的错误格式相当不宽容

    更新:

    请注意,像
    'Ball'
    这样的字段将被视为不同于
    'Ball'
    。也就是说,如果您有额外的空白,它会把事情搞砸

    您可能尝试更正的是将
    allow_whitespace=>1,
    添加到
    $csv
    对象的选项中。这将更正输入文件中任何细微的空白错误

    您还可以通过使用打印标题键来检查格式错误

    print Dumper $csv->column_names(); 
    

    在你提到的问题中,我在最后一行也写了这句话:

    ETA:如果你要剪切粘贴来尝试,请确保 制表符在数据中结转

    您是否确保您的选项卡在复制/粘贴到您的文件
    't.out'
    后仍然有效

    这个模块对数据文件中的错误格式相当不宽容

    更新:

    请注意,像
    'Ball'
    这样的字段将被视为不同于
    'Ball'
    。也就是说,如果您有额外的空白,它会把事情搞砸

    您可以尝试更正的是将
    allow_whitespace=>1,
    添加到opt