2012-03-12 79 views
2

我有以下脚本:Perl脚本错误; “未初始化的值”?

use 5.12.4; 
use strict; 
use warnings; 

say "Enter a functionality:"; 
while (<>) { 
    if (/add/) { 
     say "Enter your numbers:"; 
     my @a = (<>); 
     my $sum += $_ for @a; 
     say $sum; 
    } 
} 

当我运行这个程序,它会提示:

Enter a functionality:

我进入add和它说:

Enter your numbers: 

我上输入几个数字单独的输入行后面跟着[ctrl]Z,并得到以下错误:

Use of uninitialized value $sum in say at C:\myperl\Math-Master\math-master.pl l 
ine 11, <> line 9. 

为什么我的代码没有添加所有输入?为什么会出现这个错误?

+0

您能否更新标题以使其反映实际问题? (提示:在失败的情况下'$ _ for @ a'的结果是什么?) – 2012-03-12 22:50:30

+0

会在循环之外设置“sum”为零吗? – 2012-03-12 22:55:36

回答

2

您不能在声明语句中使用postscript循环。变量$sum应该是每个循环递增,它不能在它声明的同一个语句中。首先必须声明,然后分配给它使用PostScript循环:

my $sum; 
$sum += $_ for @a; 

您可以考虑使用List::Util这一点,并跳过临时变量@a。而移动while循环中的say

use List::Util qw(sum); 

say "Enter a functionality:"; 
while (<>) { 
    if (/add/) { 
     say "Enter your numbers:"; 
     say "Sum: ", sum(<>); 
    } 
    say "Enter a functionality:"; 
} 

但是,这是一个有点笨重。为什么不是:

while (<>) { 
    if (/add/) { 
     say "Enter your numbers, separated by space: "; 
     say "Sum: ", sum(split " ", <>); 
    } 
} 

这样,您不必按ctrl-Z(ctrl-D)来停止输入。

1

除了TLP的答案或许会考虑使用这样的事情:

chomp(my @a = (<>)); 

否则你会加入value1\n'value2\n。这当然仍然有效,但你可能在某个时候后想知道这些奇怪的结果来自哪里...

我总是错过了Perl的foldl(),但幸运的是有List::Util。它增加了一些语法糖...

use List::Util qw/sum/; 
chomp(my @a = (<>)); 
my $sum = sum @a; 
say $sum; 
+0

'foldl'不会因命名清晰而获得任何奖项,但从我可以收集的信息来看,它很像['map'](http://perldoc.perl.org/functions/map.html) – TLP 2012-03-12 23:21:12

+1

请参阅也http://stackoverflow.com/q/9115666/725418 – TLP 2012-03-12 23:23:12

0

这里有一种方法来做到这一点;比较和学习:

use 5.012; # implies 'use strict' 
use warnings; 

say "Enter a functionality:"; 
while (<>) { 
    if (/add/) { 
     say "Enter your numbers:"; 
     my @nums; 
     while (1) { 
      my $in = <>; # read one line 
      last unless $in =~ m/^\d+$/; # only numbers 
      push @nums, $in; 
     } 
     next unless @nums; 
     my $sum; 
     $sum += $_ for @nums; 
     say $sum; 
    } 
}