File Coverage

blib/lib/Devel/Backtrace/Point.pm
Criterion Covered Total %
statement 71 78 91.0
branch 24 34 70.5
condition 1 2 50.0
subroutine 14 14 100.0
pod 5 5 100.0
total 115 133 86.4


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__