(Перевод brian’s_guide.pod)
Следуйте этому руководству и берегите нервы.
Моя философия отладки
Я верю в три вещи:
1. Ничего личного
Забудьте об авторстве кода. Вы можете считать себя художником, но даже великие художники делали много ерунды. У всех код ерундовый, то есть мой код — ерунда, и ваш тоже. Смиритесь с этим. Если есть проблема, то первой мыслью должно быть «с моим ерундовым кодом что-то не так». Так вы не будете считать виновным Perl. Ничего личного.
Забудьте о том, как вы что-то делаете. Если бы ваш подход работал, вы бы это не читали. В этом нет ничего плохого, просто нужно развиваться. Все мы там будем.
2. Личная ответственность
Если есть проблема со скриптом, то это только ваша проблема. Вам нужно сделать все возможное, чтобы решить ее. Помните, что у всех остальных есть свои скрипты, то бишь свои проблемы. Сделайте домашнюю работу и попробуйте справиться сами, перед тем как дергать кого-то еще. Если вы честно перепробовали все в этом руководстве, но не решили проблему, тогда пришло время беспокоить окружающих.
3. Подход нужно менять
Исправьте все, чтобы не встретиться снова с такой же проблемой. Возможно, она в том, как вы программируете, а не в том, что. Поменяйте подход, чтобы облегчить свою жизнь. Не заставляйте Perl подстроиться под вас, потому что он этого не сделает. Подстройтесь под Perl. Это просто язык, а не образ жизни.
Мой метод
Компилируется ли ваш скрипт в строгом режиме?
Если вы не используете строгий режим, включите его. Perl-гуру являются гуру оттого, что используют strict, это позволяет решать другие задачи, изучать новые штуки и загружать работающие модули на CPAN.
Строгий режим включается прагмой strict:
use strict;
Из командной строки это можно сделать, используя опцию -M:
perl -Mstrict script.pl
После этого perl может докучать вам, но после пары недель программирования в строгом режиме ваш код станет лучше, меньше времени уйдет на отлавливание простых ошибок, а, быть может, отпадет надобность в этом руководстве.
Что за предупреждение?
Perl предупредит о многих подозрительных конструкциях. Включите предупреждения и помогите Perl помочь вам.
Используйте параметр -w в строке с интерпретатором:
#!/usr/bin/perl -w
Вы можете включить предупреждения из командной строки:
perl -w script.pl
Вы можете использовать лексические предупреждения со всякими интересными возможностями (подробности — в perldoc warnings).
use warnings;
Если предупреждения непонятны, посмотрите подробную версию в perldoc perldiag или используйте прагму diagnostics:
use diagnostics;
Решите сперва первую проблему!
Как только perl выдал вам сообщения об ошибках или предупреждения, устраните первое, а потом посмотрите, выдаются ли остальные сообщения — первая проблема и может быть их причиной.
Посмотрите на код перед строкой, на которую ссылается сообщение об ошибке!
Perl выдает предупреждения после того, как ощутит беспокойство, но не до этого. К тому времени, как perl обеспокоен, проблема уже возникла, и perl, на самом деле, находится уже после проблемы. Взгляните на пару выражений до строки под номером, указанным в предупреждении.
То ли здесь значение, какое вы думаете?
Не гадайте! На деле проверьте значение до того, как использовать его в выражении. Лучший отладчик в мире — print.
print STDERR “Значение — [$value]n”;
Я заключаю $value в скобки, чтобы видить все пробелы или переводы строк в начале или конце.
Если я имею дело с чем-то помимо скаляра, я использую Data::Dumper для вывода структур.
require Data::Dumper;
print STDERR “Хеш — “, Data::Dumper::Dumper( %hash ), “n”;
Если в значении — не то, что вы думаете, вернитесь на несколько шагов назад и попробуйте снова. Повторяйте до тех пор, пока не найдете точку, в которой значение перестает быть ожидаемым.
Также можете использовать встроенный отладчик perl, запустив perl с опцией -d. Детали — в perldoc perldebug.
perl -d script.pl
Еще есть другие отладчики или среды разработки вроде ptkdb (графический отладчик, основанный на Tk) или Komodo (IDE ActiveState, основанная на Mozilla).
Верно ли вы используете функцию?
Я программирую на Perl довольно давно, но все еще заглядываю в perldoc perlfunc чуть ли не каждый день. Что-то я просто не могу упомнить, а иногда по недосыпу меня покидают все чувства, и непонятно, почему sprintf() не печатает на экране.
Отыскать отдельную функцию с командой perldoc можно при помощи опции -f:
perldoc -f имя_функции
Если вы используете модуль, загляните в документацию, чтобы убедиться, что используете его правильно. Это делается с perldoc:
perldoc Имя::Модуля
Используете ли вы нужную специальную переменную?
И снова, я все время смотрю в perldoc perlvar. Нет, не так часто, с тех пор как нашел более удобной книжку «Perl Pocket Reference».
У вас есть нужная версия модуля?
Некоторые модули меняют поведение от версии к версии. У вас та версия модуля, о которой вы думаете? Вы можете узнать последнюю версию таким однострочником perl:
perl -MИмя::Модуля -le ‘print Имя::Модуля->VERSION’;
Если вы смотрите большинство документации не на локальной машине, а на http://www.perldoc.com/ или http://search.cpan.org/, то, вероятнее всего, вы найдете различия в версиях текстов.
Вы сделали небольшой тестовый пример?
Если вы пробуете что-то новое, или часть кода работает странно, напишите самую короткую из возможных программ, которая исполняет только тот код. Это исключит из рассмотрения большинство других вещей. Если маленькая тестовая программа делает то, что нужно, то проблема, скорее всего, не в том коде. Если программа работает неверно, то вы, возможно, нашли проблему.
Проверили ли вы среду?
Некоторые вещи зависят от переменных окружения. Вы уверены, что они верно установлены? Ваша среда совпадает с той, в которой работает программа? Помните, что CGI-программы или задачи cron могут видеть среды, отличающиеся (особенно на различных машинах) от той, что доступна из вашей интерактивной оболочки.
Perl хранит среду в %ENV. Если вам нужна одна из этих переменных, будьте готовы указать значение по умолчанию, если переменная не существует, даже на время тестирования.
Если проблема еще есть, проверьте среду:
require Data::Dumper;
print STDERR Data::Dumper::Dumper( %ENV );
Смотрели в Google?
Если у вас есть проблема, то, возможно, у кого-то была такая же. Посмотрите в Google Groups, писал ли кто нибудь об этом в comp.lang.perl.misc. Разница между людьми, задающими вопросы в USENET и отвечающими на них — в умении эффективно искать по Google Groups.
Профайлер использовали?
Если хотите прокрутить медленные участки программы, использовали ли вы профайлер? Пусть тяжелую работу за вас сделает Devel::SmallProf. Он считает количество исполнения строки кода и продолжительность процесса, после чего показывает красивый отчет.
Какой тест не работает?
Если у вас есть набор тестов, то какой тест не срабатывает? Вы должны быть способны очень быстро найти ошибку, так как каждый тест исполняет лишь малую часть кода.
Если набора тестов нет, почему бы его не сделать? Я не прошу вас писать пару тестов, если скрипт по-настоящему маленький или одноразовый. Но все другое реально выиграет от нескольких тестовых скриптов. Test::Harness делает это столь простым, что у вас нет оправданий не использовать тесты. Если нет времени, возможно, вы тратите слишком много на отладку скриптов без тестов. MakeMaker, в конце-концов, нужен не только для модулей.
Думаете вслух?
Объсните проблему вслух. По-настоящему проговорите слова.
Пару лет я имел счастье работать с очень хорошим программистом, который мог справиться практически со всем. Когда я застревал на чем-то, я шел к его столу и начинал объяснять проблему. Обычно не проходило и трех предложений, как я прерывался: «забудь, я понял» (но и он почти всегда находил решение).
Так как вам это, видимо, придется делать очень часто, советую выбрать в качестве Perl-терапевта нечто вроде плюшевой игрушки и не досаждать коллегам. У меня на столе сидит маленький мишка, и я объясняю проблемы ему. Моя подружка даже уже не обращает внимания, когда я разговариваю сам с собой.
Выглядит ли проблема иначе на бумаге?
Вы глазели на экран компьютера, и, быть может, на другом носителе вещи будут выглядеть иначе. Попробуйте посмотреть на распечатку программы.
Смотрели сегодня ТВ-шоу?
Серьезно. Сделайте перерыв. Перестаньте на время думать о проблеме и дайте отдых мозгам. Вернитесь к проблеме позже, и решение может оказаться очевидным.
Вы уменьшили свое самомнение?
Если вы еще не покончили, проблема может быть психологической. Вы можете быть эмоционально привязанными к отдельной части кода, поэтому не менять ее. Вы также можете думать, что все неверно, кроме вас. Тогда вы не считаетесь всерьез с самым вероятным источником ошибок — самим собой. Ничего не упускайте. Проверьте все.