2012-03-12 6 views
2

Я следующий сценарий:Ошибка в Perl Script; «Неинициализированное значение» ?;

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' в случае отказа?) –

+0

Будет ли установка' sum' равным нулю вне цикла, исправить? –

ответ

2

Вы не можете использовать цикл postscript в объявлении. Предполагается, что переменная $sum будет увеличивать каждый цикл, который не может быть в том же самом заявлении, которое он объявляет. Вы должны сначала объявить, а затем присвоить ей с петлей припиской:

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

Вы могли бы рассмотреть возможность использования List::Util для этого, и пропуская переменную временную @a. И перемещение 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

В дополнение к TLPs ответ вы могли бы рассмотреть возможность использования что-то вроде этого:

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

иначе вы бы добавление value1\n' и value2\n. Это, конечно же, по-прежнему будет работать, но вы можете в какой-то момент позже задаться вопросом, откуда происходят все эти странные результаты:

Я всегда пропустил что-то вроде foldl() для Perl, но, к счастью, есть 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

+1

См. также http://stackoverflow.com/q/9115666/725418 – TLP

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; 
    } 
} 
Смежные вопросы