[Kiev-pm] Данные из конфига считываются с позиции предыдущего обхода (mojolicious)

Виктор Турский koorchik at gmail.com
Sat Oct 27 13:48:24 PDT 2012


Каждый хеш хранит в себе внутренний итератор. При обращении к хешу при
помощи each - мы смещаем позицию на один элемент. Если мы доходим до
конца хеша, то позиция сбрасывается.
В данном случае мы до конца не доходим и состояние позиции сохраняется
между вызовами.
То есть, во второй раз мы уже начинаем не сначала. И мы не находим
нужный нам элемент, поскольку мы его нашли в прошлый раз(позиция уже
смещена за нужный нам элемент).Дальше мы проходим до конца по хешу и
возращаем значение переменной $test - "0" (my $test = 0;)

keys - сбрасывает итератор.
Если добавить "keys %{ $self->config->{ test } }" перед циклом, то
тесты пройдут. (но это далеко не лучшее решение)

27 октября 2012 г., 23:27 пользователь Cyrill Novgorodcev
<cynovg ÎÁ gmail.com> написал:
> Здравствуйте.
>
> Написал небольшое тестовое приложение,что бы объяснить свою проблему.
>
> основной модуль приложения lib/SmallTest.pm
>
> package SmallTest;
> use Mojo::Base 'Mojolicious';
>
> sub startup {
>   my $self = shift;
>
>   $self->plugin( 'Config' );
>
>   my $r = $self->routes;
>   $r->get('/')->to('example#welcome');
> }
>
> 1;
>
> и контроллер lib/SmallTest/Example.pm
>
> package SmallTest::Example;
> use Mojo::Base 'Mojolicious::Controller';
> #use Data::Dumper;
>
> sub welcome {
>   my $self = shift;
>   my $test = 0;
> #  $self->app->log->debug( Dumper( $self->config->{ test } ) );
>   while ( my ( $key, $val ) = each %{ $self->config->{ test } } ) {
>     if ( $test =~ $key ) {
>         $test = $val;
>         last;
>     }
>   }
>   $self->render( message => $test );
> }
>
> 1;
>
> файл конфига small_test.conf:
>
> {
>   test => {
>     0 => 'x00',
>     1 => 'x11',
>     2 => 'x22',
>   },
> }
>
> шаблон вывода templates/example/welcome.html.epl
>
> % layout 'default';
> <h2><%= $message %></h2>
>
> Теперь достаточно запустить и просто обновлять (рефрешить) окно, что
> бы увидеть, что данные из конфига считываются с позиции предыдущего
> обхода. То есть, если в предыдущий раз было найдено вхождение и был
> осуществлен принудительный выход из цикла, то в след. раз обход
> продолжится с следующего (относительно первого обхода) значения, те
> значения, которые были использованы в первом поиске - в текущем уже
> учитываться не будут. Т.к. с следующей позиции вхождение не удастся
> найти, то поиск завершится неудачей и только при третьем обновлении,
> то есть в следующий раз снова будет начат с первой позиции.
>
> В качестве костыля достаточно выводить дамп в лог (раскомментировать
> строки) и все чудесным образом начинает работать так, как и
> задумывалось. Если запускать приложение в cgi-окружении, то проблема
> не возникает. Но, даже банальный тест (см ниже) не проходит, т.к.
> используется внутренний сервер.
>
> тест-файл t/01-def.t
>
> use strict;
> use warnings;
>
> use Test::More 'no_plan';
> use Test::Mojo;
>
> my $t = Test::Mojo->new( 'SmallTest' );
> $t->get_ok('/')->status_is(200)->text_is( 'h2' => 'x00' );
> $t->get_ok('/')->status_is(200)->text_is( 'h2' => 'x00' );
>
> Теперь, собственно, вопрос: это нормальное поведение?
>
> PS: Тестовое приложение можно взять на гитхабе
> git clone https://github.com/cynovg/SmallTest
>
> --
>
>
> Всего хорошего!
> _______________________________________________
> Kiev-pm mailing list
> Kiev-pm ÎÁ pm.org
> http://mail.pm.org/mailman/listinfo/kiev-pm



-- 
Viktor Turskyi
http://webbylab.com
http://koorchik.blogspot.com


More information about the Kiev-pm mailing list