Perl的警告:未初始化值的使用在加入或串

问题描述:

我越来越:Perl的警告:未初始化值的使用在加入或串

"Use of uninitialized value in join or string at ./test_script.pl line 69, <fh> line 91." 

的代码创建这个警告是在这里:

# Write results of SQL execution to output file 
if ([email protected]) { print "\n DB Error : ", [email protected]; exit; } 
open(FH, ">$output_file") or 
     die "\n cannot write to the file $output_file. Check the file permissions"; 
while(my @row= $sth->fetchrow_array) { 
     print FH join($delimiter, @row). "\n"; 
} 

它是从“打印未来.. 。加入....“行中的”while“块,但我不确定100%是什么导致它以及如何纠正它。

$分隔符被初始化为我的$ delimiter =“|”并且@row从前一行中的$ sth操作获取它的值。

这是关于@row值的“计时”问题还是它正在处理的实际SQL查询文件中的某些内容,如警告中的“< fh>第91行”部分所示?关于如何避免警告的任何想法? 顺便说一句,该脚本工作正常,它只是产生一个警告,每个@row取值,这将产生大量的数据集拉的警告...

+0

您的查询看起来像什么或生成查询的代码是什么? – SBH 2014-11-06 17:40:50

+1

向您自己证明$分隔符有一个值。在打印之前加上这个:'print'delimiter >>> $ delimiter toolic 2014-11-06 17:41:22

+4

如果我猜测,'@ row'中的一列是'NULL'。 – nandhp 2014-11-06 17:42:01

@row可能包含一些元素有一个未定义的值,可能是因为数据库中填充@row的一列或多列为NULL

perl -we 'my @array = ("Hello",undef,"world!"); print join("|",@array) . "\n";' 

,将产生的输出是:

Use of uninitialized value $array[1] in join or string at -e line 1. 
Hello||world! 

之所以出现这种情况是因为join试图行为可以同时还在一个简单的Perl的一行像这样使用join被模仿加入一个值,如果未从“未定义”升级到“已定义”,则不会进行字符串化。字符串化undef会生成此警告消息,提醒您可能正在做一些无意的事情,并且不正确。

一个更简单的例子可能是这样的:

$ perl -we 'my $scalar; print "$scalar\n";' 
Use of uninitialized value $scalar in concatenation (.) or string at -e line 1. 

再次,我们得到了警告,因为我们要插一个未定义的值转换成字符串。插值会导致字符串化,并且未定义值的字符串化通常会引发警告,让您知道您可能犯了错误。递给join()

print FH join($delimiter, map { defined ? $_ : '' } @row) . "\n"; 

这前处理@row

如果你不介意默默地undef的升级到一个空字符串,你可以这样做。对于@row中的每个元素,如果元素具有未定义的值,则该值由空字符串替代,该字符串已定义,但视觉上很安静。

另一种可能性是$delimiter未定义。通过打印进行测试,如果事实证明是这样的话,那么需要采取措施来解决这个问题就是确保它实际上包含一个值。

只要在紧密的词汇范围内使警告静音也可以,尽管从哲学的角度来看,一种方法可以消除原因,另一种方法可以消除其中一种症状。在其他地方描述的“no warnings 'uninitialized';方法就是这样做的;沉默警告。当你知道自己正在做的事情完全正常时,你会这样做,但你也知道Perl会警告你,因为很多时候这是一个错误。这可能是这种情况;你可能会很满意,只要让join内部发生未定义值的沉默串化。如果是这种情况,请继续并且禁止警告。最重要的是,你知道它是什么意思,核实是什么造成的,然后做出明智的决定,该怎么做。

+1

的值如果有人发现这种情况,则使用defined是明确的,如图所示。它需要是map {defined $ _? $ _:''} – mark 2015-07-22 12:29:35

+0

'perl'在这里没有任何歧义,在'perldoc -f defined'中讨论了'defined'在没有其他参数的情况下回退到使用'$ _'作为参数的事实。三元运算符的使用不是不明确的。并且记录了'map'将'$ _'作为它正在迭代的列表元素的别名。这归结为风格问题,可能在PBP中提到。 – DavidO 2015-07-22 15:13:54

+0

实际上,是的,这是一个PBP问题,放入* Iterator变量*标题,第105-107页。这个PBP建议似乎没有引用歧义,而是可读性。如果可读性是关注的话,我不会不同意。 – DavidO 2015-07-22 15:27:28