
Настройка Macbook'a для web-разработки на perl'e
Описание основных проблем и их решения
Описание основных проблем и их решения
Компилятор perl'a состоит из модулей O:: (API) и B:: (реализации). На самом деле модули API, тоже находятся в namespac'e B::, поэтому, чтобы получить по ним документацию надо писать perldoc B::ModuleName. Ниже приведены примеры использования этих модулей. perldb - это перл скомпилированный с -DDEBUGGING (см. http://dsn74.livejournal.com/14749.html).
perldb -MO=Lint program_name
выводит предупреждения о всех возможных сомнительных местах в программе. Даже те, которые не показываются при perl -w, use strict и use warning.
perldb -MO=Xref program_name
генерирует список всех функций, переменных и модулей, в том числе из библиотек. Например:
Subroutine (main) Package (lexical) $FILE i16, 34 $c i26, 29, 29 $f i10, &16, 13, 16, 16
i[номер строки] - первое использование или определение
s[номер строки] - определение функции
&[номер строки] - вызов функции
подробности в perldoc B::Xref
perldb -MO=Deparse,-p program_name
Напечатает код программы в оптимизированном виде так, как интерпретатор будет его выполнять. Ключ -p - показывать скобки.
perldb -MO=Concise program_name
Показывает opcode - промежуточный код, что-то вроде внутреннего перловского ассемблера или JVM.
#!/usr/bin/perl use Benchmark; timethese($ARGV[0] || 1000000, { 'function1' => "&function1()", 'function2' => "&function2()", });Benchmark: timing 1000000 iterations of function1, function2... function1: 7 wallclock secs (6.54 usr + 0.00 sys = 6.54 CPU) @ 152905.20/s (n=1000000) function2: 4 wallclock secs (4.79 usr + 0.01 sys = 4.78 CPU) @ 209205.02/s (n=1000000) 3. Профилирование
perl -d:DProf program_name prof_result.outМодуль DProf поставляется вместе с инструментом dprofpp, который позволяет анализировать результаты профилирования. По умолчанию результат выводится в tmon.out.
dprofpp tmon.out- в результате будет список функций, отсортированный по времени, потраченном на выполнение каждой функции. Подробности в perldoc dprofpp. 4. Покрытие строк кода при выполнении Модули, используемые для определения покрытия: Devel::Coverage и Devel::Cover. Самая большая польза от этого - выяснить какие строки вообще не выполняются (они могут быть вообще не нужны или не покрыты тестированием). perl -d:Cover prog cover_prog.out perldoc Devel::Cover... 5. Что можно узнать о программе, если perl скомпилирован с опцией -DDEBUGGING? Перед компиляцией перла, надо запустить конфигуратор с -DDEBUGGING: tar -xvzf perl-5.12.2.stable.tar.gz; cd perl-5.12.2; sh Configure -Dprefix=/opt/perl/perldb -Uinstallusrbinperl -Doptimize='-g' -de -DDEBUGGING -Dusethreads; make && make test && make install PERLNAME=perldb;
Работа с командной строкой
все, что не может быть обработано отладчиком, передается perl'у. Чтобы передать команду мимо отладчика perl'у, надо вначале строки поставить +:
+p "123123";
!!команда - передать в командную строку ОС
= / !! - переопределить !! на /, теперь можно вызывать /ls /home/username
| x \%INC - листать по страничкам
x $str=~/regexp/ - по-быстрому протестировать регулярное выражение
Если переменную объявить в отладчике через my, то она будет видна только в строке объявления. Надо так
our $str=""
или
$str=""
t function() - трассировка, например
t Class->new("arg")
аналогично
s Class->new("arg") - пошаговое выполнение. Можно устанавливать breakpoint'ы.
Отладка CGI-программ
perl -d ./main.pl param1=value1 param2=value2 - передача параметров из командной строки, еще вариант:
perl -MCGI=debug ./main.pl
param1=value1
param2=value2
...
Для отладки через web-сервер, надо запустить apache в однопользовательском режиме в отдельной консоли, где и будет происходить отладка:
httpd -X -f /path/to/debughttpd.conf
В заголовке скрипта должно быть написано:
#!/usr/bin/perl -d
Запрашиваем в браузере http://host/script.pl
и в консоли, где запущен apache, запускается отладчик.
Запуск отладчика через web-сервер может потребоваться, например, для доступа к переменным окружения:
p $ENV{SERVER_SOFTWARE}
p $ENV{REQUEST_URI}
Еще бывает удаленная отладка
PERLDB_OPTS="RemotePort=host:port" perl -d main.pl
на сервере тоже надо запускать программку, которая будет читать этот порт. Я бы не стала пользоваться удаленной отладкой на настоящем сервере.
Отладка под mod_perl'ом
Выполняется с помощью Apache::DB. Компиляция mod_perl'a:
perl Makefile.PL DO_HTTPD=1 USE_APACI=1 APACHE_PREFIX=/usr/local/apache
make test install
Настройки apache:
PerlRequire /home/perltut/code/MyMod.pm PerlRequire /home/perltut/code/db.pl <Location /mymod> SetHandler perl-script PerlHandler MyMod PerlFixUpHandler +Apache::DB </Location> <VirtualHost 192.168.0.7:80> DocumentRoot /home/perltut/code/ ServerName perltut ErrorLog /home/perltut/logs/error_log CustomLog /home/perltut/logs/access_log common </VirtualHost> # db.pl use Apache::DB; Apache::DB->init;
И apache должен быть в однопользовательском режиме:
httpd -X -f ./conf/httpd.conf
Когда в браузере открывается http://192.168.0.7/perltut/mymod, в консоли с apacheм запускается отладчик.
p $ENV{SERVER_SOFTWARE} - должен выдать Apache/версия (Unix) mod_perl/версия
GUI отладчик в linux'e
perl -MCPAN -e shell -e install('Tk', 'Devel::ptkdb'); - установка в linux
ppm install Devel::ptkdb - установка в windows
ppm install Tk
perl -d:ptkdb -e 'print "looks ok\n";' - запуск
DISPLAY="ip:0.0" perl -d:ptkdb -e 0 - запуск этой строки на сервере (linux) приводит к тому, что отладочное окошко открывается на клиентское машине ip. Еще можно настроить в исходниках:
#!/usr/bin/perl -d:ptkdb
sub BEGIN{
ENV{DISPLAY}="ip:0.0";
}
Тогда отладчик будет запускаться при запросе в браузере. Чтобы в denwer'e запускался отладчик на локальном компьютере, достаточно:
#!/usr/bin/perl -d:ptkdb
Отладка forks'ов
В linux'e надо запускать отладчик из под xterm. Каждый fork будет открываться в новом окне.
Отладка Thread'ов
Perl должен быть скомпилирован с поддержкой потоков:
/Configure -Dusethreads
при отладке надо указывать флаг -dt
perl -dt ...
Специальные команды для отладки потоков:
e - печатает id потока
E - печатает список потоков, выделяет текущий
Программы, использующие POE отлаживаются обычным способом.
Отладка регулярных выражений
Три способа:
1) perl -e 'print ($str =~ /$regex/ ? "yup\n" : "nope\n")' - тестирование регулярного выражения
2) perl -Mre=debug -e "'spot' =~/[pso]+./" - отладка
3) perldb -Dr -e '/spot/' - это самый предпочтительный, но для этого perl должен быть скомпилирован специальным способом, например так:
tar -xvzf perl-5.8.5.stable.tar.gz;
cd /usr/local/src/perl-5.8.5/;
sh Configure -Dprefix=/opt/perl/perldb -Uinstallusrbinperl -Doptimize='-g' -de;
perl Makefile.PL && make test && make install PERLNAME=perldb;
perldb -Dr -e '/[^@]+\@(\w+\.)+/' - пример использования
Настройка отладчика
= новый_алиас команда - у команды появится синоним в виде новый алиас, например
= sys !!
pre-promt - выражение на perl'e вызывается каждый раз перед выводом promt'a:
< ? - показывать список установленных pre-promt'ов
< perl_expr - установить pre-promt, например < print join(', ', @pars);
<< perl_expr - добавить еще один pre-promt
< * - удалить все pre-promt'ы
post-promt - выражение на perl'е вызывает после вывода promt'а:
> ?
> perl_expr
>> perl_expr
> *
Пример использования:
< print "Time: ", scalar localtime(), "\n";
> print "Time: ", scalar localtime(), "\n";
Теперь каждый раз, при нажатии n, печатается время до выполнения строки и время после ее выполнения. В таких случаях на самом деле лучше пользоваться use Time::HiRes qw(gettimeofday).
Настройка опций отладчика
h o - в отладчике покажет список настраиваемых параметров с комментариями.
.perldb
Если в текущей папке есть файл .perldb, то при запуске отладчик его выполняет. Пример файла:
$DB::trace=1; # включить трассировку sub afterinit { # вызывается после инициализации отладчика push(@DB::typeahead, # выполнить эти команды после загрузки 'b 12', 'b 24', '< print "$_\n"', '= his !', '= sys !!', 'L', ...);
Переменная окружения PERLDB_OPTS
Позволяет настраивать отладчик, например:
"NonStop=1 LineInfo=db.out AutoTrace"
NonStop - выполнять программу без остановок, игнорирует $DB::trace=0
noTTY - неинтерактивный режим
ReadLine - если = 0, отключает поддержку readline в отладчике
RemotePort - host:port, к которому подключатся для удаленной отладки
TTY - определяет устройство ввода
В linux стрелочки могут не работать, чтобы заработали, надо в отладчике написать
use Term::ReadLine::Perl
Заменить стандартный отладчик на другой можно, изменив значением переменной окружения:
export PERL5DB="BEGIN {require 'debugger.pl'}"
где debugger.pl - новый отладчик