Таинственный ключ вышел из не где в Perl 5.14 хеш-таблица

Я использую хеш-таблицу в своем коде

my %stat = ();
# read files and do some initialization 
# like  $stat{$key} = {k1=>v1, k2=>v2, k3=>v3};
#   I have located the buggy code
# I want to do something according to c1 and c2 parsed from each line of the file
if(!exists $stat{c1}) {   # I thought I would have initialized all possible used keys here, but it is not true as seen below
    $stat{c1} = {k1=>0, k2=>0, k3=>0};
} 
if( $c1 == $c2) {
    $stat{c1}{k1}++;
} else {
    $stat{c1}{k2}++;
    $stat{c2}{k3}++;  #Note: I forgot to check whether $stat{c2} has been initialized here!
}



map {
    my $val = $stat{$_}{k1};  
    print "$val\n";     # run time error shows "use of uninitalized $val"
} keys %stat;

Я написал несколько операторов печати для отладки программы. Я обнаружил, что какое-то значение ключа загадочным образом появляется в хеш-таблице "%stat", несмотря на то, что я никогда не вставлял его! Скажем, $stat{510} каким-то образом существует, несмотря на то, что я никогда не вставляю его, но его значение (ссылка на хеш-таблицу в моем случае) не было инициализировано. Я должен написать заявление:

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

удалить ненужные ключи.

Можете ли вы сказать мне, почему может появиться какой-то загадочный ключ (keys %stat)?

Спасибо джефф

2 ответа

Решение

Можете ли вы сказать мне, почему может появиться какой-то загадочный ключ (keys %stat)?

Потому что код, который вы не показали, каким-то образом создал их.

Возможно, ты сделал $stat{510}{k1}? Имейте в виду, что

$stat{510}{k1}

коротка для

$stat{510}->{k1}

а также

$x->{...}

делает

( $x //= {} )->{...}

так

$stat{510}{k1}

делает

( $stat{510} //= {} )->{k1}

Обратите внимание, как это присваивается $stat{510}?


С помощью map как for петля нахмурилась.

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

лучше написано как

delete $stat{$_} for grep !defined($stat{$_}{k1}), keys %stat;

или даже

delete @stat{ grep !defined($stat{$_}{k1}), keys %stat };

Из-за автовивификации. Это означает, что когда вы ссылаетесь на хеш-запись, она создается без жалоб. И если вы не присваиваете значение в то время, оно инициализируется значением undefined, Так что в той части вашего кода, где у вас есть

##read files and do some initialization 

убедитесь, что вы не читаете или не пишете запись с ключом 510,

Другие вопросы по тегам