line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Devel::Backtrace::Point; |
2
|
5
|
|
|
5
|
|
22
|
use strict; |
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
109
|
|
3
|
5
|
|
|
5
|
|
17
|
use warnings; |
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
186
|
|
4
|
|
|
|
|
|
|
our $VERSION = '0.11'; |
5
|
5
|
|
|
5
|
|
19
|
use Carp; |
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
379
|
|
6
|
5
|
|
|
5
|
|
2168
|
use String::Escape qw(printable); |
|
5
|
|
|
|
|
21863
|
|
|
5
|
|
|
|
|
404
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Devel::Backtrace::Point - Object oriented access to the information caller() |
11
|
|
|
|
|
|
|
provides |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
print Devel::Backtrace::Point->new([caller(0)])->to_long_string; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 DESCRIPTION |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
This class is a nice way to access all the information caller provides on a |
20
|
|
|
|
|
|
|
given level. It is used by L, which generates an array of |
21
|
|
|
|
|
|
|
all trace points. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=cut |
24
|
|
|
|
|
|
|
|
25
|
5
|
|
|
5
|
|
28
|
use base qw(Class::Accessor::Fast); |
|
5
|
|
|
|
|
3
|
|
|
5
|
|
|
|
|
2117
|
|
26
|
5
|
|
|
5
|
|
14227
|
use overload '""' => \&to_string; |
|
5
|
|
|
|
|
4276
|
|
|
5
|
|
|
|
|
37
|
|
27
|
5
|
|
|
5
|
|
234
|
use constant; |
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
472
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
BEGIN { |
30
|
5
|
|
|
5
|
|
17
|
my @known_fields = (qw(package filename line subroutine hasargs wantarray |
31
|
|
|
|
|
|
|
evaltext is_require hints bitmask hinthash)); |
32
|
|
|
|
|
|
|
# The number of caller()'s return values depends on the perl version. For |
33
|
|
|
|
|
|
|
# instance, hinthash is not available below perl 5.9. We try and see how |
34
|
|
|
|
|
|
|
# many fields are supported |
35
|
5
|
50
|
|
|
|
41
|
my $supported_fields_number = () = caller(0) |
36
|
|
|
|
|
|
|
or die "Caller doesn't work as expected"; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# If not all known fields are supported, remove some |
39
|
5
|
|
|
|
|
19
|
while (@known_fields > $supported_fields_number) { |
40
|
0
|
|
|
|
|
0
|
pop @known_fields; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# If not all supported fields are known, add placeholders |
44
|
5
|
|
|
|
|
14
|
while (@known_fields < $supported_fields_number) { |
45
|
0
|
|
|
|
|
0
|
push @known_fields, "_unknown".scalar(@known_fields); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
5
|
|
|
|
|
3719
|
constant->import (FIELDS => @known_fields); |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=head1 METHODS |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=head2 $p->package, $p->filename, $p->line, $p->subroutine, $p->hasargs, |
54
|
|
|
|
|
|
|
$p->wantarray, $p->evaltext, $p->is_require, $p->hints, $p->bitmask, |
55
|
|
|
|
|
|
|
$p->hinthash |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
See L for documentation of these fields. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
hinthash is only available in perl 5.9 and higher. When this module is loaded, |
60
|
|
|
|
|
|
|
it tests how many values caller returns. Depending on the result, it adds the |
61
|
|
|
|
|
|
|
necessary accessors. Thus, you should be able to find out if your perl |
62
|
|
|
|
|
|
|
supports hinthash by using L: |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Devel::Backtrace::Point->can('hinthash'); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=cut |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
__PACKAGE__->mk_ro_accessors(FIELDS); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head2 $p->level |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
This is the level given to new(). It's intended to be the parameter that was |
73
|
|
|
|
|
|
|
given to caller(). |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=cut |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
__PACKAGE__->mk_ro_accessors('level'); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head2 $p->called_package |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
This returns the package that $p->subroutine is in. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
If $p->subroutine does not contain '::', then '(unknown)' is returned. This is |
84
|
|
|
|
|
|
|
the case if $p->subroutine is '(eval)'. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=cut |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub called_package { |
89
|
15
|
|
|
15
|
1
|
16
|
my $this = shift; |
90
|
15
|
|
|
|
|
27
|
my $sub = $this->subroutine; |
91
|
|
|
|
|
|
|
|
92
|
15
|
|
|
|
|
44
|
my $idx = rindex($sub, '::'); |
93
|
15
|
100
|
|
|
|
33
|
return '(unknown)' if -1 == $idx; |
94
|
12
|
|
|
|
|
45
|
return substr($sub, 0, $idx); |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=head2 $p->by_index($i) |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
You may also access the fields by their index in the list that caller() |
100
|
|
|
|
|
|
|
returns. This may be useful if some future perl version introduces a new field |
101
|
|
|
|
|
|
|
for caller, and the author of this module doesn't react in time. |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=cut |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub by_index { |
106
|
2
|
|
|
2
|
1
|
2
|
my ($this, $idx) = @_; |
107
|
2
|
|
|
|
|
3
|
my $fieldname = (FIELDS)[$idx]; |
108
|
2
|
100
|
|
|
|
8
|
unless (defined $fieldname) { |
109
|
1
|
|
|
|
|
164
|
croak "There is no field with index $idx."; |
110
|
|
|
|
|
|
|
} |
111
|
1
|
|
|
|
|
5
|
return $this->$fieldname(); |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head2 new([caller($i)]) |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
This constructs a Devel::Backtrace object. The argument must be a reference to |
117
|
|
|
|
|
|
|
an array holding the return values of caller(). This array must have either |
118
|
|
|
|
|
|
|
three or ten elements (or eleven if hinthash is supported) (see |
119
|
|
|
|
|
|
|
L). |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Optional additional parameters: |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
-format => 'formatstring', |
124
|
|
|
|
|
|
|
-level => $i |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
The format string will be used as a default for to_string(). |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
The level should be the parameter that was given to caller() to obtain the |
129
|
|
|
|
|
|
|
caller information. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=cut |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
__PACKAGE__->mk_ro_accessors('_format'); |
134
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors('_skip'); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub new { |
137
|
67
|
|
|
67
|
1
|
64
|
my $class = shift; |
138
|
67
|
|
|
|
|
104
|
my ($caller, %opts) = @_; |
139
|
|
|
|
|
|
|
|
140
|
67
|
|
|
|
|
44
|
my %data; |
141
|
|
|
|
|
|
|
|
142
|
67
|
50
|
|
|
|
128
|
unless ('ARRAY' eq ref $caller) { |
143
|
0
|
|
|
|
|
0
|
croak 'That is not an array reference.'; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
67
|
50
|
|
|
|
102
|
if (@$caller == (() = FIELDS)) { |
|
|
0
|
|
|
|
|
|
147
|
67
|
|
|
|
|
85
|
for (FIELDS) { |
148
|
737
|
|
|
|
|
961
|
$data{$_} = $caller->[keys %data] |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
} elsif (@$caller == 3) { |
151
|
0
|
|
|
|
|
0
|
@data{qw(package filename line)} = @$caller; |
152
|
|
|
|
|
|
|
} else { |
153
|
0
|
|
|
|
|
0
|
croak 'That does not look like the return values of caller.'; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
67
|
|
|
|
|
81
|
for my $opt (keys %opts) { |
157
|
112
|
100
|
|
|
|
184
|
if ('-format' eq $opt) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
158
|
2
|
|
|
|
|
3
|
$data{'_format'} = $opts{$opt}; |
159
|
|
|
|
|
|
|
} elsif ('-level' eq $opt) { |
160
|
67
|
|
|
|
|
76
|
$data{'level'} = $opts{$opt}; |
161
|
|
|
|
|
|
|
} elsif ('-skip' eq $opt) { |
162
|
43
|
|
|
|
|
44
|
$data{'_skip'} = $opts{$opt}; |
163
|
|
|
|
|
|
|
} else { |
164
|
0
|
|
|
|
|
0
|
croak "Unknown option $opt"; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
67
|
|
|
|
|
184
|
return $class->SUPER::new(\%data); |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub _virtlevel { |
172
|
1
|
|
|
1
|
|
1
|
my $this = shift; |
173
|
|
|
|
|
|
|
|
174
|
1
|
|
50
|
|
|
8
|
return $this->level - ($this->_skip || 0); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head2 $tracepoint->to_string() |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Returns a string of the form "Blah::subname called from main (foo.pl:17)". |
180
|
|
|
|
|
|
|
This means that the subroutine C from package C was called by |
181
|
|
|
|
|
|
|
package C in C line 17. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
If you print a C object or otherwise treat it as a |
184
|
|
|
|
|
|
|
string, to_string() will be called automatically due to overloading. |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Optional parameters: -format => 'formatstring' |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
The format string changes the appearance of the return value. It can contain |
189
|
|
|
|
|
|
|
C<%p> (package), C<%c> (called_package), C<%f> (filename), C<%l> (line), C<%s> |
190
|
|
|
|
|
|
|
(subroutine), C<%a> (hasargs), C<%e> (evaltext), C<%r> (is_require), C<%h> |
191
|
|
|
|
|
|
|
(hints), C<%b> (bitmask), C<%i> (level), C<%I> (level, see below). |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
The difference between C<%i> and C<%I> is that the former is the argument to |
194
|
|
|
|
|
|
|
caller() while the latter is actually the index in $backtrace->points(). C<%i> |
195
|
|
|
|
|
|
|
and C<%I> are different if C<-start>, skipme() or skipmysubs() is used in |
196
|
|
|
|
|
|
|
L. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
If no format string is given, the one passed to C will be used. If none |
199
|
|
|
|
|
|
|
was given to C, the format string defaults to 'default', which is an |
200
|
|
|
|
|
|
|
abbreviation for C<%s called from %p (%f:%l)>. |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Format strings have been added in Devel-Backtrace-0.10. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=cut |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
my %formats = ( |
207
|
|
|
|
|
|
|
'default' => '%s called from %p (%f:%l)', |
208
|
|
|
|
|
|
|
); |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
my %percent = ( |
211
|
|
|
|
|
|
|
'p' => 'package', |
212
|
|
|
|
|
|
|
'c' => 'called_package', |
213
|
|
|
|
|
|
|
'f' => 'filename', |
214
|
|
|
|
|
|
|
'l' => 'line', |
215
|
|
|
|
|
|
|
's' => 'subroutine', |
216
|
|
|
|
|
|
|
'a' => 'hasargs', |
217
|
|
|
|
|
|
|
'w' => 'wantarray', |
218
|
|
|
|
|
|
|
'e' => 'evaltext', |
219
|
|
|
|
|
|
|
'r' => 'is_require', |
220
|
|
|
|
|
|
|
'h' => 'hints', |
221
|
|
|
|
|
|
|
'b' => 'bitmask', |
222
|
|
|
|
|
|
|
'i' => 'level', |
223
|
|
|
|
|
|
|
'I' => '_virtlevel', |
224
|
|
|
|
|
|
|
); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub to_string { |
227
|
17
|
|
|
17
|
1
|
28
|
my ($this, @opts) = @_; |
228
|
|
|
|
|
|
|
|
229
|
17
|
|
|
|
|
16
|
my %opts; |
230
|
17
|
100
|
|
|
|
42
|
if (defined $opts[0]) { # check that we are not called as stringification |
231
|
2
|
|
|
|
|
5
|
%opts = @opts; |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
17
|
|
|
|
|
33
|
my $format = $this->_format(); |
235
|
|
|
|
|
|
|
|
236
|
17
|
|
|
|
|
93
|
for my $opt (keys %opts) { |
237
|
2
|
50
|
|
|
|
4
|
if ($opt eq '-format') { |
238
|
2
|
|
|
|
|
5
|
$format = $opts{$opt}; |
239
|
|
|
|
|
|
|
} else { |
240
|
0
|
|
|
|
|
0
|
croak "Unknown option $opt"; |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
17
|
100
|
|
|
|
35
|
$format = 'default' unless defined $format; |
245
|
17
|
100
|
|
|
|
39
|
$format = $formats{$format} if exists $formats{$format}; |
246
|
|
|
|
|
|
|
|
247
|
17
|
|
|
|
|
15
|
my $result = $format; |
248
|
17
|
|
|
|
|
76
|
$result =~ s{%(\S)} { |
249
|
61
|
50
|
|
|
|
340
|
my $percent = $percent{$1} or croak "Unknown symbol %$1\n"; |
250
|
61
|
|
|
|
|
125
|
my $val = $this->$percent(); |
251
|
61
|
50
|
|
|
|
248
|
defined($val) ? printable($val) : 'undef'; |
252
|
|
|
|
|
|
|
}ge; |
253
|
|
|
|
|
|
|
|
254
|
17
|
|
|
|
|
160
|
return $result; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=head2 $tracepoint->to_long_string() |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
This returns a string which lists all available fields in a table that spans |
260
|
|
|
|
|
|
|
several lines. |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Example: |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
package: main |
265
|
|
|
|
|
|
|
filename: /tmp/foo.pl |
266
|
|
|
|
|
|
|
line: 6 |
267
|
|
|
|
|
|
|
subroutine: main::foo |
268
|
|
|
|
|
|
|
hasargs: 1 |
269
|
|
|
|
|
|
|
wantarray: undef |
270
|
|
|
|
|
|
|
evaltext: undef |
271
|
|
|
|
|
|
|
is_require: undef |
272
|
|
|
|
|
|
|
hints: 0 |
273
|
|
|
|
|
|
|
bitmask: \00\00\00\00\00\00\00\00\00\00\00\00 |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
hinthash is not included in the output, as it is a hash. |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=cut |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub to_long_string { |
280
|
1
|
|
|
1
|
1
|
3
|
my $this = shift; |
281
|
|
|
|
|
|
|
return join '', |
282
|
|
|
|
|
|
|
map { |
283
|
|
|
|
|
|
|
"$_: " . |
284
|
10
|
100
|
|
|
|
53
|
(defined ($this->{$_}) ? printable($this->{$_}) : 'undef') |
285
|
|
|
|
|
|
|
. "\n" |
286
|
|
|
|
|
|
|
} grep { |
287
|
1
|
50
|
|
|
|
4
|
! /^_/ && 'hinthash' ne $_ |
|
11
|
|
|
|
|
39
|
|
288
|
|
|
|
|
|
|
} FIELDS; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=head2 FIELDS |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
This constant contains a list of all the available field names. The number of |
294
|
|
|
|
|
|
|
fields depends on your perl version. |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=cut |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
1 |
299
|
|
|
|
|
|
|
__END__ |