Perl에서 호출 스택 목록을 얻으려면 어떻게해야합니까?
Perl 확장에서 현재 위치에 선행하는 임의 깊이의 하위 호출에 대한 하위 + 모듈 목록에 액세스 할 수있는 방법이 있습니까?
일부 Perl 모듈 (.pm)을 변경해야합니다. 워크 플로는 cgi 펼쳐를 통해 웹 페이지에서 시작되어 데이터를 만나는 모듈로 끝나는 여러 모듈 / 수업을 통해 입력을 전달합니다. 선을 따라 어딘가에 데이터가 변경되어 어디를 찾아야합니다.
Devel :: StackTrace를 사용할 수 있습니다 .
use Devel::StackTrace;
my $trace = Devel::StackTrace->new;
print $trace->as_string; # like carp
Carp의 흔적처럼 동작하지만 프레임을 더 잘 제어 할 수 있습니다.
한 가지 문제는 참조가 많게 화되어 참조 된 값이 변경됩니다. 그러나 PadWalker 를 사용하여 전체 데이터를 인쇄 할 수 있습니다.
Carp::longmess
당신이 원하는 것은 표준입니다.
use Carp qw<longmess>;
use Data::Dumper;
sub A { &B; }
sub B { &C; }
sub C { &D; }
sub D { &E; }
sub E {
# Uncomment below if you want to see the place in E
# local $Carp::CarpLevel = -1;
my $mess = longmess();
print Dumper( $mess );
}
A();
__END__
$VAR1 = ' at - line 14
main::D called at - line 12
main::C called at - line 10
main::B called at - line 8
main::A() called at - line 23
';
나는이 잠수함을 생각 해 전투 이제 선택적인 축복 행동으로!
my $stack_frame_re = qr{
^ # Beginning of line
\s* # Any number of spaces
( [\w:]+ ) # Package + sub
(?: [(] ( .*? ) [)] )? # Anything between two parens
\s+ # At least one space
called [ ] at # "called" followed by a single space
\s+ ( \S+ ) \s+ # Spaces surrounding at least one non-space character
line [ ] (\d+) # line designation
}x;
sub get_stack {
my @lines = split /\s*\n\s*/, longmess;
shift @lines;
my @frames
= map {
my ( $sub_name, $arg_str, $file, $line ) = /$stack_frame_re/;
my $ref = { sub_name => $sub_name
, args => [ map { s/^'//; s/'$//; $_ }
split /\s*,\s*/, $arg_str
]
, file => $file
, line => $line
};
bless $ref, $_[0] if @_;
$ref
}
@lines
;
return wantarray ? @frames : \@frames;
}
발신자 는 그렇게 할 수있는 그보다 더 많은 정보를 원할 수 있습니다.
이 코드는 추가 모듈없이 작동 합니다 . 필요한 곳에하십시오.
my $i = 1;
print STDERR "Stack Trace:\n";
while ( (my @call_details = (caller($i++))) ){
print STDERR $call_details[1].":".$call_details[2]." in function ".$call_details[3]."\n";
}
이이기도 Carp::confess
하고 Carp::cluck
.
더 예쁜 것 : Devel :: PrettyTrace
use Devel::PrettyTrace;
bt;
비 핵심 모듈을 사용할 수 있고 피하고 싶은 경우 다음과 같은 간단한 서브 루틴이 있습니다.
#!/usr/bin/perl
use strict;
use warnings;
sub printstack {
my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash);
my $i = 1;
my @r;
while (@r = caller($i)) {
($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash) = @r;
print "$filename:$line $subroutine\n";
$i++;
}
}
sub i {
printstack();
}
sub h {
i;
}
sub g {
h;
}
g;
다음과 같은 출력을 생성합니다.
/root/_/1.pl:21 main::i
/root/_/1.pl:25 main::h
/root/_/1.pl:28 main::g
또는 oneliner :
for (my $i = 0; my @r = caller($i); $i++) { print "$r[1]:$r[2] $r[3]\n"; }
여기 에서 발신자에 대한 문서를 찾을 수 있습니다 .
참고 URL : https://stackoverflow.com/questions/229009/how-can-i-get-a-call-stack-listing-in-perl
'ProgramingTip' 카테고리의 다른 글
"not in"조건에 따라 데이터 프레임에서 행 삭제 (0) | 2020.11.30 |
---|---|
그래프에서 노드를 제거하거나 전체 기본 그래프를 제거하거나 (0) | 2020.11.30 |
PHP에서 사용할 압축 방법은 무엇입니까? (0) | 2020.11.30 |
F- 조화 측정이 및 재현율 측정의 산술 평균이 아닌 평균 인 이유는 무엇입니까? (0) | 2020.11.29 |
React Native 프로젝트에서 ios 폴더를 어떻게 다시 생성 할 수 있습니까? (0) | 2020.11.29 |