Perl警告:在联接或字符串中使用未初始化的值 [英] Perl warning: Use of uninitialized value in join or string

查看:400
本文介绍了Perl警告:在联接或字符串中使用未初始化的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到:

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

创建此警告的代码在这里:

The code creating this warning is here:

# 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";
}

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

It is coming from the "print ... join ...." line in the "while" block, but I'm not sure 100% on what is causing it and how to rectify it.

$ delimiter早先被初始化为我的$ delimiter = |

The $delimiter is initialized earlier as my $delimiter = "|" and the @row is getting its values from the $sth operation in the previous line.

这是关于@row值的定时问题,还是它在其中如警告的< fh>第91行所示,正在处理的实际SQL查询文件是什么?关于如何避免警告的任何想法?
顺便说一句,脚本运行良好,它只为获取的每个@row值生成一个警告,这对大型数据集提取操作会产生大量警告...

Is this a "timing" issue regarding the @row values or is it something in the actual SQL query file being processed, as indicated by the "< fh> line 91" part of the warning? Any ideas on how I can avoid the warnings? BTW, the script works fine, it just generates a warning for each @row value fetched, which creates a huge amount of warnings on a large data set pull...

推荐答案

@row 可能包含一些具有未定义值的元素,可能是因为数据库中的一个或多个列填充 @row 的是 NULL 。可以在仍然像这样的简单Perl内衬中使用 join 时模仿该行为:

@row may contain some elements that have an undefined value, probably because one or more of the columns in the database that populated @row was NULL. The behavior can be mimicked while still using join in a simple Perl one-liner like this:

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 是试图加入一个不会被字符串化的值,而不会从未定义升级到已定义。字符串化 undef 会产生此警告消息,以提醒您您可能在执行无意且不正确的操作。

The reason this happens is because join is trying to join a value that doesn't stringify without being upgraded from "undefined" to "defined". Stringifying undef produces this warning message to alert you that you may be doing something unintentional, and incorrect.

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

An even simpler example could be this:

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

...或...

perl -wE 'say "" . undef'

再次,我们得到警告,因为我们将未定义的值插入到字符串中(在第一种情况),或强制字符串化(第二种情况)。插值会导致字符串化,而未定义值的字符串化通常会发出警告,告知您可能有错误。

Again, we get the warning because we're interpolating an undefined value into a string (in the first case), or forcing stringification (in the second case). Interpolation causes stringification, and stringification of an undefined value generally throws a warning to let you know you may have made a mistake.

如果您不介意静默升级 undef 为一个空字符串,您可以这样做:

If you don't mind silently upgrading the undef's to an empty string, you could do this:

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

此操作在处理前先处理 @row join()。对于 @row 中的每个元素,如果该元素具有未定义的值,则将该值替换为空字符串,该字符串已定义但在视觉上安静。

This pre-processes @row before handing it to join(). For each element in @row, if the element has an undefined value, that value is replaced by an empty string, which is defined but visually quiet.

另一种可能性是 $ delimiter 未定义。通过打印进行测试,如果是这种情况,则修复该问题所需要采取的步骤就是简单地确保它实际上包含一个值。

The other possibility is that $delimiter is undefined. Test for that by printing it, and if that turns out to be the case, the steps you will need to take to fix it are to simply make sure that it actually contains a value.

在严格的词汇范围内简单地使警告沉默也是可以的,尽管从哲学的角度来看,一种方法可以消除原因,而另一种可以消除其中一种症状。在其他地方介绍的 没有警告'未初始化'; 方法就是这样做;将警告静音。当您知道自己做的很好时,可以这样做,但是您也可以知道Perl会警告您,因为很多时候这是一个错误,这种情况可能是这样;您可能很高兴让 join 。如果是这种情况,请继续发出警告,最重要的是要知道它的意思,确认是什么原因,然后就如何处理做出明智的决定。

Simply silencing the warnings in a tight lexical scope could be ok as well, though from a philosophical standpoint, one method removes the cause, and the other removes one of the symptoms. The "no warnings 'uninitialized'; method described elsewhere does just that; silences the warning. You would do this when you know you're doing something perfectly Ok, but you also know that Perl is going to warn you about it because many times it's a mistake. This could be such a situation; you may be perfectly happy with just letting silent stringification of an undefined value happen inside of the join. And if that's the case, go ahead and squelch the warning. The most important thing is that you know what it means, verify what is causing it, and then make an informed decision as to what to do about it.

这篇关于Perl警告:在联接或字符串中使用未初始化的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆