在串联(。)中使用未初始化的值或在mksmksmks.pl第63行使用字符串

时间:2012-08-15 20:29:15

标签: perl initialization

我写了一些代码,我不确定错误是什么。我收到了错误:

  

在串联(。)中使用未初始化的值或在mksmksmks.pl第63行使用字符串

我的代码如下:

for(my $j = 0; $j < $num2; $j++) {
  print {$out} "$destination[$j]|$IP_one_1[$j]|$IP_one_2[$j]|$reached[$j]|$IP_two_1[$j]|$IP_two_2[$j]\n";`
}

3 个答案:

答案 0 :(得分:9)

这意味着@destination@IP_one_1@IP_one_2@reached的其中一个元素尚未定义(尚未分配值) ,或者已被赋值为undef。您需要在源处检测(并阻止)未定义的值,或者稍后期望并处理它们。由于您启用了warnings(这是一件好事),Perl会提醒您,您的代码正在尝试连接一个字符串,其中一个连接的值未定义。

考虑以下示例:

perl -wE 'my @x = (); $x[0] = "Hello "; $x[2] = "world!";  say "@x"'

在此示例中,$x[0]有一个值,$x[2]有值,但$x[1]没有。当我们将@x插入到双引号构造中时,它会扩展为[element 0 (Hello )]<space>[element 1 (undef)]<space>[element 2 (world!)]undef元素作为空字符串插入,并发出警告。当然,默认情况下,数组插值会在每个元素之间注入空格字符。因此,在上面的示例中,我们看到了Hello <interpolation-space>(undef upgrades to empty string here)<interpolation-space>world!

您可能会调查的一个示例是,一个或多个阵列的总大小与其他阵列的大小不同。例如,如果@IP_one_2的元素少于其他元素,或者$num2的值大于任何数组中元素的数量。

将以下内容放在脚本顶部附近并再次运行:

use diagnostics;

当我在警告和诊断下运行以下单行时:

$ perl -wMdiagnostics -e '$a=$a; print "$a\n"'

我得到以下输出,如果你添加use diagnostics;,你会得到类似的东西......当你第一次学习Perl的警告时,这是一个非常有用的工具。

  

在连接(。)中使用未初始化的值$ a或在-e中使用字符串   第1行(#1)

     

(W未初始化)使用未定义的值,就像它已经存在一样      定义。它被解释为&#34;&#34;或者是0,但也许这是一个错误。      要禁止此警告,请为变量分配定义的值。

     

为了帮助您弄清楚未定义的内容,perl将尝试告诉您      未定义的变量(如果有)的名称。在某些情况下      它不能这样做,所以它也告诉你你使用了什么操作      未定义的值。但请注意,perl会优化您的程序      警告中显示的操作可能不一定出现      字面上在你的程序中。例如,&#34;那个$ foo&#34;通常是      优化成&#34;那&#34; 。 $ foo,警告将参考      连接(。)运算符,即使没有。在      你的计划。

答案 1 :(得分:0)

也许我的例子对某人有用。假设变量$ x是从数据库初始化的。它可能包含未定义的值,这是正常的。我们需要在控制台上显示其值。作为负责任的程序员,我们决定使用“使用警告FATAL =>“ all”;“。在这种情况下,脚本将失败。

perl -e 'use strict; use warnings FATAL => "all"; my $x; print("x=$x\n"); print("DONE\n");'

返回:

Use of uninitialized value $x in concatenation (.) or string at -e line 1.

在这种情况下,您可以使用

if(defined($x)){...}else{...}

但是,如果只想打印一个值,这并不漂亮。

perl -e 'use strict; use warnings FATAL => "all"; my $x; print("x=".($x//"null")."\n"); print("DONE\n");'

打印:

x=null
DONE

因为表达式$ x //“ null”会检查是否定义了//之前的内容,如果未定义则返回//之后的内容。

答案 2 :(得分:-1)

如果您使用eq "",则不会发出任何警告消息。

但是如果你使用eq " "(这里你可以看到一个空格),那么它会给出这个警告信息:

  

在连接(。)或字符串....

中使用未初始化的值