В проекте образовался вот такой код:
use SOAP::Lite;
my $soap = SOAP::Lite->service("file:very_useful_service.wsdl");
...
for my $uid (@uids){
my $data = process_uid($uid);
eval { $soap->update($uid, $data) },
write_log("update failed for uid $uid") if $@;
}
На первый взгляд все хорошо… Но в действительности все плохо!
Большая часть записей не обновляется, но сообщений в логе нет.
Зато в логе есть предупреждения о записях, которые на самом деле успешно обработаны.
Внимание к мелким деталям – залог успеха.
Все дело в запятой вместо точки с запятой. Код следует исправить так:
my $data = process_uid($uid);
- eval { $soap->update($uid, $data) },
+ eval { $soap->update($uid, $data) };
write_log("update failed for uid $uid") if $@;
Первоначальный же вариант работает так:
for my $uid (@uids){
my $data = process_uid($uid);
if($@){
eval { $soap->update($uid, $data) };
write_log("update failed for uid $uid");
}
}
То есть если к началу цикла переменная $@ была сброшена, то ни одна запись из @uids
вообще не будет обработана. Если же к началу цикла переменная $@ оказывается непустой, то метод update
будет вызван для нескольких первых элементов массива @uids
… Ровно до первого удачного срабатывания. После этого переменная $@ снова станет пустой, и остаток цикла отработает вхолостую.
А в лог попадут записи обо всех записях, которые обрабатываются методом update
, независимо от результата. То есть если к началу цикла переменная $@ была пустой, то в лог ничего не попадет. Если же $@ была непустой, то в лог попадут записи о первых нескольких uid’ах – вплоть до первого, на котором update
сработает успешно.