Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Перехват вызовов несуществующих процедур


Автор: Ramirez 26.5.2006, 17:18
Столкнулся с необходимостью перехватывать если вызвана процедура не определенная в данном модуле. Попробовал сделать с помощью функции AUTOLOAD - не работает. Никак не пойму почему.

Есть модуль:
Код

package My::Mod;

use strict;

sub AUTOLOAD {
    use vars qw($AUTOLOAD);
    return "Function $AUTOLOAD not exist"
}


Вызываю таким способом:
Код

....
$result = eval("use My::Mod; My::Mod::$function_name;");
$result = $@ if $@;
return $result;
...


И  все равно пишет: Bareword "....." not allowed while "strict subs" in use at (eval 10) line 1.  

Автор: korob2001 27.5.2006, 06:11
Так а зачем тебе перехватывать ошибку, если у тебя есть AUTOLOAD, по сути она это делает за тебя? В твоём случае eval не перехватывает ошибки, так как на самом деле её и нет, просто вместо несуществующего метода запускается AUTOLOAD который возвращает строку.
Насколько я понял, ты хочешь предотвратить аварийное завершение программы, если был вызван не существующий метод, с выводом сообщения об этом. Если да, то можно сделать так:
Код
package My::Mod;

use strict;

AUTOLOAD {
    use vars qw($AUTOLOAD);
    warn "Function $AUTOLOAD not exist"
}

1;

Здесь изменился только return на warn, так как если мы будем возвращать строку, то потом не сможем отличить её от того, что мог бы вернуть метод My::Mod::test(), если бы он существовал, от сообщения об ошибке.

Код
#!/usr/bin/perl -w
use strict;
use My::Mod;
My::Mod::test();

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

Если же ты хочешь перехватить ошибку с помощью eval, тогда нужно убрать AUTOLOAD и пропустить вызов метода через eval.
Код
package My::Mod;

use strict;

1;

Основной код:
Код
#!/usr/bin/perl -w
use strict;
use My::Mod;

eval { My::Mod::test() };
warn "Fuck: $@\n" if $@;

print "Last string\n";

Здесь последняя строка нужна для того, что бы показать, что программа лишь предупреждает тебя и продолжает свою работу. Если же не перехватить ошибку, то программа завершит свою работу ещё при вызове несуществующего метода и разумеется последней строки ты не увидешь.
Код
#!/usr/bin/perl -w
use strict;
use My::Mod;

My::Mod::test();

print "Last string\n";
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)