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   35 use strict;
  5         10  
  5         168  
3 5     5   30 use warnings;
  5         10  
  5         221  
4             our $VERSION = '0.11';
5 5     5   28 use Carp;
  5         9  
  5         544  
6 5     5   6157 use String::Escape qw(printable);
  5         41384  
  5         655  
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   48 use base qw(Class::Accessor::Fast);
  5         9  
  5         4230  
26 5     5   24782 use overload '""' => \&to_string;
  5         5473  
  5         45  
27 5     5   299 use constant;
  5         13  
  5         580  
28              
29             BEGIN {
30 5     5   20 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       58 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         24 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         25 while (@known_fields < $supported_fields_number) {
45 0         0 push @known_fields, "_unknown".scalar(@known_fields);
46             }
47              
48 5         4757 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 11     11 1 22 my $this = shift;
90 11         35 my $sub = $this->subroutine;
91              
92 11         57 my $idx = rindex($sub, '::');
93 11 100       34 return '(unknown)' if -1 == $idx;
94 9         47 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 5 my ($this, $idx) = @_;
107 2         3 my $fieldname = (FIELDS)[$idx];
108 2 100       7 unless (defined $fieldname) {
109 1         216 croak "There is no field with index $idx.";
110             }
111 1         6 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 45     45 1 60 my $class = shift;
138 45         107 my ($caller, %opts) = @_;
139              
140 45         48 my %data;
141              
142 45 50       110 unless ('ARRAY' eq ref $caller) {
143 0         0 croak 'That is not an array reference.';
144             }
145              
146 45 50       150 if (@$caller == (() = FIELDS)) {
    0          
147 45         90 for (FIELDS) {
148 495         1110 $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 45         114 for my $opt (keys %opts) {
157 68 100       164 if ('-format' eq $opt) {
    100          
    50          
158 2         4 $data{'_format'} = $opts{$opt};
159             } elsif ('-level' eq $opt) {
160 45         112 $data{'level'} = $opts{$opt};
161             } elsif ('-skip' eq $opt) {
162 21         41 $data{'_skip'} = $opts{$opt};
163             } else {
164 0         0 croak "Unknown option $opt";
165             }
166             }
167              
168 45         197 return $class->SUPER::new(\%data);
169             }
170              
171             sub _virtlevel {
172 1     1   2 my $this = shift;
173              
174 1   50     5 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 13     13 1 26 my ($this, @opts) = @_;
228              
229 13         17 my %opts;
230 13 100       32 if (defined $opts[0]) { # check that we are not called as stringification
231 2         5 %opts = @opts;
232             }
233              
234 13         38 my $format = $this->_format();
235              
236 13         75 for my $opt (keys %opts) {
237 2 50       7 if ($opt eq '-format') {
238 2         5 $format = $opts{$opt};
239             } else {
240 0         0 croak "Unknown option $opt";
241             }
242             }
243              
244 13 100       34 $format = 'default' unless defined $format;
245 13 100       34 $format = $formats{$format} if exists $formats{$format};
246              
247 13         17 my $result = $format;
248 13         55 $result =~ s{%(\S)} {
249 45 50       380 my $percent = $percent{$1} or croak "Unknown symbol %$1\n";
250 45         122 my $val = $this->$percent();
251 45 50       266 defined($val) ? printable($val) : 'undef';
252             }ge;
253              
254 13         143 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 2 my $this = shift;
281 10 100       65 return join '',
282             map {
283 11 50       43 "$_: " .
284             (defined ($this->{$_}) ? printable($this->{$_}) : 'undef')
285             . "\n"
286             } grep {
287 1         3 ! /^_/ && 'hinthash' ne $_
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__