Perl警告:在连接或字符串中使用未初始化的值

Vas*_*Vas 6 perl warnings dbi

我越来越:

"Use of uninitialized value in join or string at ./test_script.pl line 69, <fh> line 91."
Run Code Online (Sandbox Code Playgroud)

创建此警告的代码如下:

# Write results of SQL execution to output file
if ($@) { print "\n DB Error : ", $@; 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";
}
Run Code Online (Sandbox Code Playgroud)

它来自"while"块中的"print ... join ...."行,但我不确定100%是由什么引起它以及如何纠正它.

$ delimiter先前初始化$ delimiter ="|" 并且@row从前一行的$ sth操作中获取其值.

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

Dav*_*idO 11

@row可能包含有一个未定义的值,可能是因为居住在数据库中的列的一个或多个一些元素@rowNULL.可以模仿行为,同时仍然使用join简单的Perl单线程,如下所示:

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

将产生的输出是:

Use of uninitialized value $array[1] in join or string at -e line 1.
Hello||world!
Run Code Online (Sandbox Code Playgroud)

发生这种情况的原因是因为join尝试加入一个没有字符串化的值而没有从"未定义"升级到"已定义".字符串化undef会产生此警告消息,提醒您可能正在做一些无意识且不正确的事情.

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

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

同样,我们得到警告,因为我们将未定义的值插入到字符串中.插值会导致字符串化,并且未定义值的字符串化通常会发出警告,让您知道您可能犯了错误.

如果您不介意将undefs 静默升级为空字符串,则可以执行以下操作:

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

@row在将其交给之前进行预处理join().对于每个元素@row,如果元素具有未定义的值,则该值将替换为空字符串,该字符串已定义但在视觉上很安静.

另一种可能性$delimiter是未定义.通过打印来测试它,如果事实证明是这样的话,你需要采取的修复步骤就是确保它实际上包含一个值.

简单地在严格的词汇范围内消除警告也是可以的,尽管从哲学的角度来看,一种方法可以消除原因,另一种方法可以消除其中一种症状." no warnings 'uninitialized';其他地方描述的方法就是这样做的;沉默警告.当你知道你正在做一些完美的事情时,你会这样做但是你也知道Perl会警告你,因为很多时候它是一个错误.这可能在这样的情况下;你可能会非常高兴只是让一个未定义的值的静音字符串发生在内部join.如果是这样的话,继续并压制警告.最重要的是你知道这意味着什么,验证是什么导致它,然后做出明智的决定,如何处理它.

  • 万一有人发现它,则如图所示,对define的使用是不明确的。它需要被映射{定义$ _?$ _:''} (2认同)