File Coverage

lib/Devel/ebug/Plugin/StackTrace.pm
Criterion Covered Total %
statement 45 53 84.9
branch 19 22 86.3
condition 9 18 50.0
subroutine 7 7 100.0
pod 0 3 0.0
total 80 103 77.6


line stmt bran cond sub pod time code
1             package Devel::ebug::Plugin::StackTrace;
2              
3 19     19   11566 use strict;
  19         42  
  19         569  
4 19     19   92 use warnings;
  19         32  
  19         640  
5 19     19   102 use Scalar::Util qw(blessed);
  19         32  
  19         1100  
6 19     19   105 use base qw(Exporter);
  19         32  
  19         19544  
7             our @EXPORT = qw(stack_trace stack_trace_human stack_trace_human_args);
8              
9             our $VERSION = '0.64'; # VERSION
10              
11             # return the stack trace
12             sub stack_trace {
13 16     16 0 105 my($self) = @_;
14 16         123 my $response = $self->talk({ command => "stack_trace" });
15 16 50       56 return @{$response->{stack_trace}||[]};
  16         121  
16             }
17              
18             # return the stack trace in a human-readable format
19             sub stack_trace_human {
20 14     14 0 4457 my($self) = @_;
21 14         33 my @human;
22 14         77 my @stack = $self->stack_trace;
23 14         107 foreach my $frame (@stack) {
24 15         120 my $subroutine = $frame->subroutine;
25 15         132 my $package = $frame->package;
26 15         142 my @args = $frame->args;
27 15         123 my $first = $args[0];
28 15         28 my $first_class = ref($first);
29 15         187 my($subroutine_class, $subroutine_method) = $subroutine =~ /^(.+)::([^:])+?$/;
30             # warn "first: $first, first class: $first_class, package: $package, subroutine: $subroutine ($subroutine_class :: $subroutine_method)\n";
31              
32 15 50 66     411 if (defined $first && blessed($first) && $subroutine =~ /^${first_class}::/ &&
    50 33        
    100 33        
    100 66        
      33        
      66        
33             $subroutine =~ /^$package/) {
34 0         0 $subroutine =~ s/^${first_class}:://;
35 0         0 shift @args;
36 0         0 push @human, "\$self->$subroutine" . $self->stack_trace_human_args(@args);
37             } elsif (defined $first && blessed($first) && $subroutine =~ /^${first_class}::/) {
38 0         0 $subroutine =~ s/^${first_class}:://;
39 0         0 shift @args;
40 0         0 my($name) = $first_class =~ /([^:]+)$/;
41 0         0 $first = '$' . lc($name);
42 0         0 push @human, "$first->$subroutine" . $self->stack_trace_human_args(@args);
43             } elsif ($subroutine =~ s/^${package}:://) {
44 11         65 push @human, "$subroutine" . $self->stack_trace_human_args(@args);
45             } elsif (defined $first && $subroutine_class eq $first) {
46 1         5 shift @args;
47 1         10 push @human, "$first->new" . $self->stack_trace_human_args(@args);
48             } else {
49 3         33 push @human, "$subroutine" . $self->stack_trace_human_args(@args);
50             }
51             }
52 14         194 return @human;
53             }
54              
55             sub stack_trace_human_args {
56 42     42 0 116 my($self, @args) = @_;
57 42         105 foreach my $arg (@args) {
58 40 100       338 if (not defined $arg) {
    100          
    100          
    100          
    100          
    100          
59 3         24 $arg = "undef";
60             } elsif (ref($arg) eq 'ARRAY') {
61 1         13 $arg = "[...]";
62             } elsif (ref($arg) eq 'HASH') {
63 1         4 $arg = "{...}";
64             } elsif (ref($arg)) {
65 10         72 my($name) = ref($arg) =~ /([^:]+)$/;
66 10         37 $arg = '$' . lc($name);
67             } elsif ($arg =~ /^-?[\d.]+$/) {
68             # number, do nothing
69             } elsif ($arg =~ /^[\w:]*$/) {
70 2         12 $arg =~ s/([\'\\])/\\$1/g;
71 2         11 $arg = qq{'$arg'};
72             } else {
73 9         41 $arg =~ s/([\'\\])/\\$1/g;
74 9         37 $arg = qq{"$arg"};
75             }
76             }
77 42         275 return '(' . join(", ", @args) . ')';
78             }
79              
80             1;
81              
82             __END__