Как работает область переменных Perl в цикле while в строгом режиме? - PullRequest
2 голосов
/ 07 октября 2010

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

Следующий код работает, как и предполагалось, без , используйте строгий

  my %hash = ();

  while (my %hash = %{$qhand->fetchrow_hashref()} ) {
    push(@results, {%hash});
  }

, но когда строгий включен, выдает следующую ошибку:

Невозможно использовать неопределенное значение в качестве ссылки на HASH в строке [имя файла] XX (строка оператора while).

Может ли кто-нибудь сказать мне, что я делаю неправильно, и каково строгое правило, что я выставляюсь напоказ?

Ответы [ 4 ]

8 голосов
/ 07 октября 2010

Вы нарушаете refs часть строгого . Когда вы пытаетесь использовать не ссылочное значение в качестве ссылки, Perl хочет создать «символическую ссылку», которая обычно не то, что вам нужно, хотя она молча продолжает программу (вероятно, не «работает», а просто продолжает). Включив ограничения, вы ловите эти случаи.

В вашем примере и ответе Джонатана похоже, что вы делаете много акробатических операций, чтобы отменить хеш-ссылки, просто чтобы снова сделать их хеш-ссылками. Есть ли причина, по которой вы не просто оставляете это как ссылку на хэш?

while( my $href = $qhand->fetchrow_hashref ) {
  push @results, $href;
  }

И, если вы просто хотите получить все результаты в виде хеш-ссылок, для этого есть метод DBI, поэтому вы можете пропустить цикл while:

my $results_array_ref = $qhand->fetchall_arrayref( {} );
3 голосов
/ 07 октября 2010

Это ошибка времени выполнения (после того, как скрипт некоторое время работал), а не ошибка времени компиляции, не так ли?

Вам нужно проверить, что хэш-ссылка вернулась из $qhand->fetchrow_hashref() (из Perl DBI ) действителен перед преобразованием ссылки на хэш в хэш.Когда больше нет строк для извлечения, вы получаете undef, и вы не можете преобразовать undef в %hash.

Вы также не хотите, чтобы два хэша назывались %hash- либо в цикле, либо не в цикле, но не в обоих.

  while (my $href = $qhand->fetchrow_hashref())
  {
      my %hash = %{$href};
      push(@results, {%hash});
  }
1 голос
/ 16 января 2013

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

my %rtn;
my $hr = $handle->fetchrow_hashref;
if($hr)
{
    do
    {
        %rtn=%{$hr};
        ...snip...


        ...snip...
        $hr = $handle->fetchrow_hashref;
    }
    while ($hr);
}

Установите скаляр ($ hr) на ожидаемую ссылку ($ handle-> fetchrow_hashref) для проверки на ноль (if ($ hr)) перед циклом и перед приведением (% {}), затем после того, как закончите Ссылка получить следующий. Как только он заканчивается нулем при следующем вызове выборки, который прерывает цикл, и вы продолжаете без забот.

0 голосов
/ 07 октября 2010

Я не эксперт по Perl, но, вероятно, это приведение к хешу при вызове функции $qhand->fetchrow_hashref(). Если эта функция уже возвращает хеш, почему бы просто не пропустить приведение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...