[Kiev-pm] Данные из конфига считываются с позиции предыдущего обхода (mojolicious)
Maxim Vuets
maxim.vuets at gmail.com
Sat Oct 27 14:30:10 PDT 2012
On Sat, Oct 27, 2012 at 11:48:24PM +0300, Виктор Турский wrote:
>Каждый хеш хранит в себе внутренний итератор. При обращении к хешу при
>помощи each - мы смещаем позицию на один элемент. Если мы доходим до
>конца хеша, то позиция сбрасывается.
>В данном случае мы до конца не доходим и состояние позиции сохраняется
>между вызовами.
Мне эта "особенность" и похожая ситуация стоила когда-то нескольких
часов полного недоумения. Был конфиг. файл вида:
target_name => {
foo => 'bar',
baz => [qw(100 200 300)],
quux => {checkbox => 1},
}
Мне нужно было вынести общий параметр quux в секцию DEFAULT.
В результате получился странный результат: на веб-странице состояние
этого checkbox-а для каждой секции чередовалось.
Оказалось, что автор кода для обработки конфига использовал each не по
назначению, а для мнимой красоты в коде:
if (ref $param_val eq 'HASH') {
my ($control, $value)= each %$val;
...
}
Я сделал этот hashref общим для всех секций, как и его внутренний
each-итератор. Получилось, что в одном случае был нормальный результат
(флажок стоял), а в другом --- пустой список как признак окончания
итерации (флажок был сброшен).
>keys - сбрасывает итератор.
>Если добавить "keys %{ $self->config->{ test } }" перед циклом, то
>тесты пройдут. (но это далеко не лучшее решение)
...
>> while ( my ( $key, $val ) = each %{ $self->config->{ test } } ) {
>> if ( $test =~ $key ) {
>> $test = $val;
>> last;
>> }
>> }
Лучшим решением будет не использовать while+each и last. Вместо:
my $config= $self->config->{test};
for my $key (keys %$config) {
my $val= $config->{$key};
...
}
--
maxim.vuets.name
More information about the Kiev-pm
mailing list