неинициализированное значение perl в ... error - PullRequest
0 голосов
/ 23 октября 2011

Я продолжаю получать ошибки инициализации в этом коде при строгом использовании и не могу понять, почему. Я установил область действия для всех переменных - и коды запускаются. Просто не понимаю уродливых ошибок.

2/15/2002   Joe   155
2/15/2002   Mike  108
2/15/2002   Pete  209
2/22/2002   Joe   158
2/22/2002   Mike  99
2/22/2002   Pete  163
3/1/2002    Joe   172
3/1/2002    Mike  125
#!/usr/bin/perl -w
our %dates;
foreach my $line (<>) {
    chomp $line;
    my ($this_date, $this_name, $this_score) = split /\s+/, $line;
    my ($record_name, $record_score) = split /\|/, $dates{$this_date};
    if ($this_name && $this_score) {
            if ($this_score > $record_score) {
                    $dates{$this_date} = join "|", ($this_name, $this_score);
            }
    }
}

foreach my $date (keys %dates) {
    my ($name, $score ) = split /\|/, $dates{$date};
    print " The high_scored for $date was $name with $score\n";
shortcasper@shortcasper-laptop:~/perl$ ./hash_bowl bowl_linux
Use of uninitialized value in split at ./hash_bowl line 8,  line 7.
Use of uninitialized value $record_score in numeric gt (>) at ./hash_bowl line 10,    line 7.
Use of uninitialized value in split at ./hash_bowl line 8,  line 7.
Use of uninitialized value $record_score in numeric gt (>) at ./hash_bowl line 10,    line 7.
The high_scored for 3/1/2002 was Joe with 172
The high_scored for 2/15/2002 was Pete with 209
shortcasper@shortcasper-laptop:~/perl$

Ответы [ 3 ]

6 голосов
/ 23 октября 2011

Вы должны use warnings вместо использования -w.

Причина, по которой он жалуется, состоит в том, что в первый раз, когда вы встречаетесь с определенным днем, $dates{$this_date} равен undef (потому что он никогда не был установлен),Разделение, которое дает вам предупреждение и составляет $record_name и $record_score undef (вызывая ваше второе предупреждение при сравнении $this_score с $record_score).Код работает, потому что численно undef считается 0, но генерирует предупреждения.

Простое исправление заключается в использовании вместо него $dates{$this_date} || '|0'.Это обеспечивает значение по умолчанию для новых дат, устанавливая $record_name в пустую строку и $record_score в 0:

use strict;
use warnings;

our %dates;
foreach my $line (<DATA>) {
    chomp $line;
    my ($this_date, $this_name, $this_score) = split /\s+/, $line;
    my ($record_name, $record_score) = split /\|/, $dates{$this_date} || '|0';
    if ($this_name && $this_score) {
            if ($this_score > $record_score) {
                    $dates{$this_date} = join "|", ($this_name, $this_score);
            }
    }
}

foreach my $date (keys %dates) {
    my ($name, $score ) = split /\|/, $dates{$date};
    print " The high_scored for $date was $name with $score\n";
}

__DATA__
2/15/2002   Joe   155
2/15/2002   Mike  108
2/15/2002   Pete  209
2/22/2002   Joe   158
2/22/2002   Mike  99
2/22/2002   Pete  163
3/1/2002    Joe   172
3/1/2002    Mike  125

Но вы должны прочитать Perl Data Structures Cookbook и рассмотретьиспользуя сложную структуру данных вместо того, чтобы join и split ваши данные просто хранить их в хэше.

2 голосов
/ 23 октября 2011

Мне кажется, что ваш хэш %dates инициализирован, а его значения - нет. Ваш код пытается использовать значение $dates{$this_date} до его фактической установки (что происходит несколькими строками позже).

0 голосов
/ 23 октября 2011

% date - пустой хэш.Поэтому $ date {$ this_date} становится "undef"

Измените ваше внутреннее состояние, как показано ниже, чтобы оно работало;если нет старых записей, он вставит в хеш даты.

 if ( !(defined  $record_score) || $this_score > $record_score) {
                $dates{$this_date} = join "|", ($this_name, $this_score);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...