File Coverage

blib/lib/Devel/Trace/More.pm
Criterion Covered Total %
statement 27 44 61.3
branch 5 14 35.7
condition 4 11 36.3
subroutine 9 12 75.0
pod 3 4 75.0
total 48 85 56.4


line stmt bran cond sub pod time code
1             package Devel::Trace::More;
2              
3              
4             =head1 NAME
5              
6             Devel::Trace::More - Like Devel::Trace but with more control
7              
8             =head1 VERSION
9              
10             Version 0.05
11              
12             =head1 SYNOPSIS
13              
14             #!/usr/bin/perl -d:Trace::More
15              
16             use Devel::Trace::More qw{ filter_on };
17            
18             filter_on('blah');
19              
20             filter_on(qr/blah/);
21              
22             filter_on(sub { my ($p, $file, $line, $code) = @_; ... });
23              
24             # or
25              
26             $IS_INTERESTING = sub { my ($p, $file, $line, $code) = @_; ... };
27              
28             =head1 DESCRIPTION
29              
30             This module will print out every line of code as it executes when used under
31             the perl debugger. By default all executed lines will print to STDERR. By
32             calling filter_on with a code ref, regex ref, a scalar, or by setting
33             $Devel::Trace::More::IS_INTERESTING directly then only those lines that are
34             'interesting' will be returned.
35              
36             If filter_on is given a scalar or a regular expression reference then the
37             file name of the code being executed or the line of code itself that matches
38             the given patter will be printed. Passing in a code ref is the same as setting
39             $IS_INTERESTING itself. Setting the filter this way will allow you to do
40             more complicated things like filtering on just the module name or the line number
41             of the code. $IS_INTERESTING can be changed in different places in the code if
42             needed.
43              
44             Caveat: Using regular expressions to filter what gets printed can cause unexected
45             issues if the code being debugged relies on the regular expression global variables.
46             Use with caution!
47              
48             =cut
49              
50 1     1   33296 use strict;
  1         2  
  1         39  
51 1     1   6 use warnings;
  1         1  
  1         30  
52              
53 1     1   5 use Exporter;
  1         6  
  1         46  
54              
55 1     1   6 use base 'Exporter';
  1         2  
  1         254  
56             our @EXPORT_OK = qw{ trace filter_on output_to };
57              
58             our $VERSION = '0.05';
59              
60             our $IS_INTERESTING = sub { return 1; };
61             our $TRACE = 1;
62             our $OUT = *STDERR;
63              
64             # This is the important part. The rest is just fluff.
65             sub DB::DB {
66 0 0   0 0 0 return unless $TRACE;
67 0         0 my ($p, $f, $l) = caller;
68            
69             # have no idea how to do this with strict on
70 1     1   5 no strict 'refs';
  1         2  
  1         59  
71 0         0 my $code = \@{"::_<$f"};
  0         0  
72 1     1   4 use strict 'refs';
  1         2  
  1         587  
73 0 0       0 my $code_line = defined($code->[$l]) ? $code->[$l] : '';
74 0         0 chomp($code_line);
75            
76 0 0 0     0 print $OUT ">> $f:$l: $code_line\n" if $OUT && $IS_INTERESTING->($p, $f, $l, $code_line);
77             }
78              
79             =head1 FUNCTIONS
80              
81             =head2 filter_on(...)
82              
83             Takes a string, code ref, or regular expression ref and sets the IS_INTERESTING code ref appropriately.
84              
85             =over 1
86              
87             =item String
88              
89             A string will cause the line of code to be printed if either the filename or the code line has the
90             string in it.
91              
92             =item Code Ref
93              
94             A code ref passed will just set $IS_INTERESTING to it, saves a few characters of typing.
95              
96             =item RegEx Ref
97              
98             The line of code will be printed if the regular expression matches either the file name or the line of code
99              
100             =back
101              
102             =cut
103              
104             sub filter_on {
105 3     3 1 11 my $filter = shift;
106              
107 3 100       31 if ( uc( ref($filter) ) eq 'REGEXP') {
    100          
    50          
108 1   66 2   20 $IS_INTERESTING = sub { my ($p, $file, $line_num, $code_line) = @_; return $file =~ $filter || $code_line =~ $filter; };
  2         10  
  2         47  
109             }
110             elsif ( uc( ref($filter) ) eq 'CODE') {
111 1         4 $IS_INTERESTING = $filter;
112             }
113             elsif (! ref($filter) ) {
114 1   66 2   10 $IS_INTERESTING = sub { my ($p, $file, $line_num, $code_line) = @_; return ( index($file, $filter) > -1) || ( index($code_line, $filter) > -1); };
  2         6  
  2         22  
115             }
116             else {
117 0           die "I don't know how to handle that filter!";
118             }
119             }
120              
121             =head2 trace('on') or trace('off')
122              
123             Turns the printing of code on or off
124              
125             =cut
126              
127             my %tracearg = ('on' => 1, 'off' => 0);
128             sub trace {
129 0     0 1   my $arg = shift;
130 0           $arg = $tracearg{$arg} while exists $tracearg{$arg};
131 0           $TRACE = $arg;
132             }
133              
134             =head2 output_to($filename)
135              
136             Given a filename the code lines will get printed to the file instead of STDERR.
137             Can be called with different filenames at different points in the script if need be.
138             By default the file will be open for reading and will be either created or cleared.
139             You can input '>>' as a param to have the trace keep appending.
140              
141             =cut
142              
143             sub output_to {
144             # have to turn trace off because messing with filehandles while
145             # it's tracing itself might cause it to die
146 0     0 1   trace('off');
147 0           my $filename = shift;
148 0   0       my $mode = shift || '>';
149              
150             # There can be cases where STDOUT/STDERR messed with in the code
151             # which will cause problems if $OUT isn't cleared first
152 0           $OUT = undef;
153              
154 0 0         open $OUT, $mode, $filename or die "Can't open file $filename : $!";
155 0           trace('on');
156             }
157              
158             1;
159             __END__