Почему я должен использовать 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 было бы лучше в таких ситуациях, поскольку он обеспечивает полную трассировку стека.

Другие вопросы по тегам