2012-05-02 1 views
0

У меня есть код ниже:Почему это определенное значение не распознается как ссылка на пакет или объект?

my $content = $response->decoded_content((charset => 'UTF-8')); 
my $feed = XML::Feed->parse(\$content) || $logger->error("When retrieving $URL: ", XML::Feed->errstr); 
if (defined $feed) { 
    for my $entry ($feed->entries) { 
     #DO SOMETHING 
    } 
} 

Для некоторых сайтов, XML :: FEED, говоря, что он не может определить тип корма. Это то, на что я должен смотреть, но на данный момент это не мой вопрос. Этот пример кода находится внутри цикла while, я извлекаю разные RSS, и я хотел бы, чтобы сценарий работал, даже когда некоторые URL-адреса потерпели неудачу.

Определенная функция, кажется, не работает, как я получаю сообщение об ошибке:

Невозможно вызвать метод «запись» без упаковки или объекта ссылки

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

+1

Тег подходит для используемого вами языка. – Lion

+0

О да, извините, сделано – ehretf

+0

Вы проверили ** $ content ** перед его разбором? – tuxuday

ответ

1

Сначала вам нужно проверить значение $ feed.

Сообщение об ошибке, которое вы описываете, очевидно: $ feed не является ссылкой на пакет/объект, но может быть простым хэшем, например. Так оно и определено.

Добавить мою любимую линию отладки прямо перед, если (определен):

warn Data::Dumper->new([ $feed ],[ '*feed' ])->Sortkeys(1)->Dump();use Data::Dumper; 

и вы увидите значение в хороший способ. Без тестирования я бы сказал, что $ feed содержит результат вашего регистратора, который может быть 1 или 0 или что-то в этом роде, потому что вы задаете значение $ feed для XML :: Feed-> parse, и если это не так, успешное (неопределенное) - результат ошибки $ logger->.

Вы бы лучше написать это нравится:

my $feed = XML::Feed->parse(\$content); 

if (defined $feed) { 
    for my $entry ($feed->entries) { 
     #DO SOMETHING 
    } 
} 
else { 
    $logger->error("When retrieving $URL: ", XML::Feed->errstr); 
} 

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

+0

Спасибо за ответ. Предлагаемый вами код работает как шарм. На самом деле, я не понимаю, почему, но похоже, что получение XML :: Feed-> errstr задает $ feed целому числу. Поэтому тестирование $ feed с помощью define() после извлечения XML :: Feed-> errstr больше не работает – ehretf

0

Сообщение об ошибке означает, что он говорит: $feed не является ни пакетом, ни ссылкой на объект. Он проходит тест defined, потому что существует множество определенных значений, которые не являются ни пакетами, ни ссылками на объекты.

В данном конкретном случае, вы видите эту ошибку, потому что вы misuing ||:

my $feed = XML::Feed->parse(\$content) || $logger->error("When retrieving $URL: ", XML::Feed->errstr); 

Если parse вызов должен терпеть неудачу и вернуть undef, это имеет значение

my $feed = (undef || $logger->error("When retrieving $URL: ", XML::Feed->errstr)); 

, который оценивает до

my $feed = $logger->error("When retrieving $URL: ", XML::Feed->errstr); 

. Возвращаемое значение $logger->error неизвестно мне, но предположительно это не пакет и ссылка на объект. И если бы это было так, вероятно, было бы неправильным вставить переменную с именем $feed.

The documentation for XML::Feed упоминает разбор конструкции как

Это не то же самое. Их соответствующие правила приоритета составляют || и or подходят для разных применений; в частности, вы должны использовать только ||, если вы хотите, чтобы значение было в правой части чего-то. Не используйте его только для побочного эффекта короткого замыкания.

Вы можете решить это, заменив || на or, чтобы получить правильный заказ для оценки. Пока вы там, вы, вероятно, также должны устранить избыточный тест defined.

Смежные вопросы