2012-03-12 59 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; 
    } 
}