perl帮助使用perl模块排除错误消息
我正在使用论坛上的这个工具测试perl脚本。我获取了样本数据并将其放在一个单独的文件中,然后使用open以这种方式进行尝试 我不明白为什么我会变得不自信。我得到消息: 在。/h.pl第15行第4行的联接或字符串中使用未初始化的值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
#!/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