Как я могу распечатать все выполненные подпрограммы?
Например, у меня есть следующий скрипт Perl
{
package A;
{
package B;
sub _y {
print "Just Another Perl Hacker\n";
}
}
sub _x {
print "Hello world!\n";
B::_y();
}
}
use strict;
use warnings;
_x();
Как я могу напечатать каждую выполненную подпрограмму с квалификатором пакета в STDERR или любой файл журнала?
Например, из приведенного выше сценария я ожидаю увидеть следующий вывод:
1 A::_x()
2 B::_y()
Я предполагаю, что это возможно сделать с отладчиком, таким как Devel::NYTProf, но я не нашел конкретных модулей отладчика или их параметров для этой простой задачи.
Есть идеи?
3 ответа
Это можно сделать с помощью стандартного отладчика perl:
$ PERLDB_OPTS="NonStop frame=1" perl -d prog.pl
entering CODE(0x260cd78)
entering strict::import
entering CODE(0x260cd18)
entering warnings::import
Package try.pl.
entering DB::Obj::_init
entering A::_x
Hello world!
entering B::_y
Just Another Perl Hacker
(Обратите внимание, что я должен был изменить _x();
в A::_x();
чтобы ваш код работал.)
Если вы хотите поместить вывод в файл, добавьте LineInfo=filenamehere
, Увидеть perldoc perldebug
для деталей. (В частности, если вы измените frame=2
Вы также получаете сообщения для возврата из подпрограмм.)
CODE
ссылки для неявного BEGIN
вокруг use
заявления:
use strict;
действительно означает
BEGIN {
require "strict.pm";
strict->import();
}
Размышление об отладочных модулях ставит вас на правильный путь. Когда включен режим отладки, Perl вызывает функцию DB::DB()
на каждом этапе выполнения в вашей программе. Отсюда вы можете извлечь название подпрограммы из caller
встроенный (который будет включать в себя имя пакета), и выводить его по своему усмотрению.
Начните с файла с именем Devel/AllSubs.pm
где-то в вашем @INC
дорожка:
package Devel::AllSubs;
my $count = 0;
my $last_sub = '::';
sub DB::DB {
my ($pkg, $file, $line,$sub) = caller(1);
if ($sub ne $last_sub) {
print STDERR ++$count," $sub\n";
$last_sub = $sub;
}
}
1;
А затем запустите вашу программу как
$ perl -d:AllSubs script.pl
Образец вывода:
1 A::_x
Hello world!
2 B::_y
Just Another Perl Hacker
Альтернативное решение, использующее уже упомянутый Devel:: NYTProf ( точнее, профилировщик вместо отладчика), которое не требует написания дополнительного кода и дает гораздо больше информации.
% perl -d:NYTProf yourscript.pl
Это по умолчанию создаст nytprof.out
файл. Затем вы можете сделать:
% nytprofcalls nytprof.out
который даст вам подробную информацию о звонке. Пример скрипта:
use strict;
sub f1 {
print "hi;\n";
f2();
}
sub f2 {
print "hi2\n";
}
f1();
и образец вывода:
main::f1;main::f2 30
main::f1;main::CORE:print 124
main::f1;main::f2;main::CORE:print 40
main::BEGIN@1 4262
main::f1 113
main::BEGIN@1;strict::import 39
main::BEGIN@1;strict::BEGIN@7 396
main::BEGIN@1;strict::BEGIN@7;strict::CORE:match 58
Вы можете видеть, что NYTProf также перечисляет вызовы основной функции (CORE::print), среди прочего.
В качестве бонуса вы можете увидеть весь вывод профиля, используя:
% nytprofhtml
затем откройте страницу отчета, например, используя:
% firefox nytprof/index.html
Вы можете увидеть выполненные подпрограммы (упорядоченные по продолжительности), сколько раз они выполнялись и многое другое.