Почему я должен использовать Carp вместо warn в Perl?
Люди продолжают приводить мне примеры с карпом, а не предупреждать. Зачем? Что делает карпа лучше, чем предупредить?
4 ответа
Карп дает вам больше информации о том, откуда пришло сообщение (контекст)
#!/usr/bin/perl
use Carp;
foo();
bar();
baz();
sub foo {
warn "foo";
}
sub bar {
carp "bar";
}
sub baz {
foo();
bar();
}
производит
foo at ./foo.pl line 9.
bar at ./foo.pl line 13
main::bar() called at ./foo.pl line 6
foo at ./foo.pl line 10.
bar at ./foo.pl line 14
main::bar() called at ./foo.pl line 19
main::baz() called at ./foo.pl line 7
довольно глупо для этой маленькой программы, но она пригодится, когда вы хотите узнать, кто вызвал метод carp'ing.
Я использую warn
для скриптов и простых программ, и Carp
внутри любых модулей. Carp
Подпрограммы используют имя файла и номер строки, где была вызвана ваша текущая подпрограмма, так что легче найти, кто вызвал проблему (а не только где проблема проявилась).
Дамиан рекомендует Carp
вместо warn
в "Отчете о сбое" в Perl Best Practices, но не делает различий между сценариями как конструкциями кода верхнего уровня и модулями как компонентами, которые используют программы.
В последнее время я больше не заботился об этом, потому что я использовал Log::Log4perl для обработки всего этого.
carp лучше работает для отладки внутри модулей. Если вы пишете только простой сценарий, вы не получите никакой выгоды. Из документации Карпа:
Подпрограммы Carp полезны в ваших собственных модулях, потому что они действуют как die() или warn(), но с сообщением, которое, скорее всего, будет полезно для пользователя вашего модуля. В случае cluck, confess и longmess этот контекст является сводкой каждого вызова в стеке вызовов. Для более короткого сообщения вы можете использовать карпа или квака, которые сообщают об ошибке как откуда ваш модуль был вызван. Нет никакой гарантии, что именно в этом и была ошибка, но это хорошее обоснованное предположение.
Carp
сообщает об ошибках с точки зрения звонящего. Это полезно для модулей, где вы обычно хотите предупредить о неправильном использовании (например, отсутствующий аргумент) и идентифицировать место, где произошла ошибка, а не то, где она была обнаружена. Это особенно важно для служебных функций, которые могут использоваться во многих местах.
Большинство авторов используют warn
в сценариях и carp
в модулях. Изредка пользуюсь warn
внутри модуля, когда я хочу, чтобы сообщение об ошибке отражало проблему в реализации модуля (например, случай, который он должен поддерживать, но не поддерживает). Можно утверждать, что cluck
было бы лучше в таких ситуациях, поскольку он обеспечивает полную трассировку стека.