Как я могу распечатать все выполненные подпрограммы? - PullRequest
0 голосов
/ 16 декабря 2018

Например, у меня есть следующий скрипт 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 ]

0 голосов
/ 17 декабря 2018

Это можно сделать с помощью стандартного отладчика 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();
}
0 голосов
/ 20 декабря 2018

Альтернативное решение, использующее уже упомянутый 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

Вы можете увидеть подпрограммы, которыебыли казнены (приказано, как долго они бегут), сколько раз они были запущены, и многое другое.

0 голосов
/ 16 декабря 2018

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