Почему «undef» не обнаруживается этим фрагментом Perl?

Я ожидаю, что блок во втором операторе if будет введен из-за значения undef, но журналы показывают, что он не вводится.

sub getcmd{
  my $self = $_[0];
  if ( $self->_recv == OK ){
      push @{$self->{'log'}}, ['NOTICE', "OK"];
      return "My command";          
  }
  push @{$self->{'log'}}, ['ERROR', "Did not get OK back"];
  return undef;
}

...

if (!($ret = $self->getcmd)){
  push @{$self->{'log'}}, ['ERROR', "failed to read after asking for NEXT"];
}
else {
  push @{$self->{'log'}}, ['ERROR', "'undef' not detected in next()"];
}

Файл журнала показывает:

[Fri May  8 19:25:56 2009]: ERROR: Did not get OK back
[Fri May  8 19:26:02 2009]: ERROR: 'undef' not detected in next()

Любые идеи с благодарностью принимаются.

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

  • Я добавил $ret в getcmd(), чтобы имитировать то, что происходит в функции ведения журнала, которая просто выводит текущее значение $ret, которое является глобальной переменной, всегда используемой для захвата возвращаемых значений.
  • Я обрезал сообщения журнала и пропустил лишнее «назад».

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

Я вернусь и посмотрю еще раз. Думаю, это то, что вы получаете, когда пытаетесь взглянуть на чей-то «средний» Perl после тринадцатичасового рабочего дня, пытаясь закончить что-то для проекта, который «должен быть запущен в понедельник»!

Я не писал код, а просто унаследовал его. Код был написан парой человек, которые думают, что им не нужны «вонючие предупреждения или ограничения».

Представьте себе 800 строк Perl и множество «если», но никаких других утверждений! Никакого защитного кодирования! 8-О

Еще раз спасибо за вашу помощь.

ваше здоровье,


person Rob Wells    schedule 09.05.2009    source источник
comment
Небольшая вещь: разница в временных метках заставляет меня подозревать, что на самом деле между вызовом getcmd() и вторым оператором журнала гораздо больше кода - код точно такой, как вы представили?   -  person j_random_hacker    schedule 09.05.2009
comment
Меня смущает то, что $ret используется и не объявлен в getcmd. И каково его фактическое значение в if/else?   -  person Anonymous    schedule 09.05.2009
comment
Первое сообщение журнала пришло не из показанной вами функции getcmd; сообщение говорит обратно, а код нет.   -  person Jonathan Leffler    schedule 09.05.2009
comment
@Anonymous: возможно, $ret является пакетной или глобальной переменной. Возможно, код не работает под «строгим использованием»; и '-w' (он же 'использовать предупреждения;').   -  person Jonathan Leffler    schedule 09.05.2009


Ответы (3)


Я думаю, что здесь происходит что-то более сложное - эти сообщения журнала кажутся разделенными 6 секундами, и нет никакого способа, чтобы это заняло 6 секунд для оператора push, возврата и проверки if.

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

person Jonathan Rupp    schedule 09.05.2009

Сведенный к минимуму, это печатает «undef обнаружен».

#!/bin/perl -w

use strict;

sub getcmd
{
    return undef;
}

my $ret;

if (!($ret = getcmd()))
{
    print "undef detected\n";
}
else
{
    print "undef undetected\n";
}

Следовательно, ваша проблема, скорее всего, в том, что $self->getcmd() не возвращает undef, хотя вы думаете, что должен.

person Jonathan Leffler    schedule 09.05.2009

Используйте отладчик perl (perl -d), чтобы просмотреть код и посмотреть, что происходит. При отладке кода важно освободить свой разум от любых предположений.

Кроме того, эти строки обязательны перед каждой программой Perl:

use strict;
use warnings;
person amarillion    schedule 09.05.2009