File Coverage

blib/lib/Carp/REPL.pm
Criterion Covered Total %
statement 36 51 70.5
branch 8 20 40.0
condition 1 6 16.6
subroutine 6 7 85.7
pod 1 1 100.0
total 52 85 61.1


line stmt bran cond sub pod time code
1             package Carp::REPL;
2 2     2   514118 use strict;
  2         2  
  2         76  
3 2     2   7 use warnings;
  2         4  
  2         49  
4 2     2   42 use 5.006000;
  2         8  
  2         425  
5              
6             our $VERSION = '0.18';
7              
8             our $noprofile = 0;
9             our $bottom_frame = 0;
10              
11             sub import {
12 2     2   15 my $nodie = grep { $_ eq 'nodie' } @_;
  3         8  
13 2         3 my $warn = grep { $_ eq 'warn' } @_;
  3         5  
14 2         3 my $test = grep { $_ eq 'test' } @_;
  3         4  
15 2         3 $noprofile = grep { $_ eq 'noprofile'} @_;
  3         5  
16 2         3 my $repl = grep { $_ eq 'repl' } @_;
  3         5  
17              
18 2 50       8 if ($repl) {
19              
20 0         0 require Sub::Exporter;
21 0         0 my $import_repl = Sub::Exporter::build_exporter(
22             {
23             exports => ['repl'],
24             into_level => 1,
25             }
26             );
27              
28             # get option of 'repl'
29 0         0 my $seen;
30 0 0 0     0 my ($maybe_option) = grep { $seen || $_ eq 'repl' && $seen++ } @_;
  0         0  
31              
32             # now do the real 'repl' import
33 0 0       0 $import_repl->( __PACKAGE__, 'repl',
34             ref $maybe_option ? $maybe_option : ()
35             );
36             }
37            
38 2 100       13 $SIG{__DIE__} = \&repl unless $nodie;
39 2 50       7 $SIG{__WARN__} = \&repl if $warn;
40              
41 2 50       1035 if ($test) {
42 0         0 require Test::Builder;
43 0         0 my $ok = \&Test::Builder::ok;
44              
45 2     2   11 no warnings 'redefine';
  2         4  
  2         578  
46             *Test::Builder::ok = sub {
47 0     0   0 local $Test::Builder::Level = $Test::Builder::Level + 1;
48 0         0 my $passed = $ok->(@_);
49 0         0 local $bottom_frame = $Test::Builder::Level;
50 0 0       0 repl("Test failure") if !$passed;
51 0         0 return $passed;
52 0         0 };
53             }
54             }
55              
56             sub repl {
57 2   33 2 1 452 my $quiet = @_ && !defined($_[0]);
58              
59 2 50       107 warn @_, "\n" unless $quiet; # tell the user what blew up
60              
61 2         484 require Devel::REPL::Script;
62              
63 2         311026 my ($runner, $repl);
64 2 50       8 if ($noprofile) {
65 0         0 $repl = $runner = Devel::REPL->new;
66             }
67             else {
68 2         23 $runner = Devel::REPL::Script->new;
69 2         434962 $repl = $runner->_repl;
70             }
71              
72 2         37 $repl->load_plugin('Carp::REPL');
73              
74 2 50       3769 warn $repl->stacktrace unless $quiet;
75              
76 2         1903 $runner->run;
77             }
78              
79             1;
80              
81             __END__
82              
83             =head1 NAME
84              
85             Carp::REPL - read-eval-print-loop on die and/or warn
86              
87             =head1 SYNOPSIS
88              
89             The intended way to use this module is through the command line.
90              
91             perl -MCarp::REPL tps-report.pl
92             Can't call method "cover_sheet" without a package or object reference at tps-report.pl line 6019.
93              
94             # instead of exiting, you get a REPL!
95              
96             $ $form
97             27B/6
98              
99             $ $self->get_form
100             27B/6
101              
102             $ "ah ha! there's my bug, I thought get_form returned an object"
103             ah ha! there's my bug, I thought get_form returned an object
104              
105             =head1 USAGE
106              
107             =head2 C<-MCarp::REPL>
108              
109             =head2 C<-MCarp::REPL=warn>
110              
111             Works as command line argument. This automatically installs the die handler for
112             you, so if you receive a fatal error you get a REPL before the universe
113             explodes. Specifying C<=warn> also installs a warn handler for finding those
114             mysterious warnings.
115              
116             =head2 C<use Carp::REPL;>
117              
118             =head2 C<use Carp::REPL 'warn';>
119              
120             Same as above.
121              
122             =head2 C<use Carp::REPL 'nodie';>
123              
124             Loads the module without installing the die handler. Use this if you just want
125             to run C<Carp::REPL::repl> on your own terms.
126              
127             =head2 C<use Carp::REPL 'test';>
128              
129             =head2 C<-MCarp::REPL=test>
130              
131             Load a REPL on test failure! (as long as it uses L<Test::More/ok>)
132              
133             =head1 FUNCTIONS
134              
135             =head2 repl
136              
137             This module's interface consists of exactly one function: repl. This is
138             provided so you may install your own C<$SIG{__DIE__}> handler if you have no
139             alternatives.
140              
141             It takes the same arguments as die, and returns no useful value. In fact, don't
142             even depend on it returning at all!
143              
144             One useful place for calling this manually is if you just want to check the
145             state of things without having to throw a fake error. You can also change any
146             variables and those changes will be seen by the rest of your program.
147              
148             use Carp::REPL 'repl';
149              
150             sub involved_calculation {
151             # ...
152             $d = maybe_zero();
153             # ...
154             repl(); # $d = 1
155             $sum += $n / $d;
156             # ...
157             }
158              
159             Unfortunately if you instead go with the usual C<-MCarp::REPL>, then
160             C<$SIG{__DIE__}> will be invoked and there's no general way to recover. But you
161             can still change variables to poke at things.
162              
163             =head1 COMMANDS
164              
165             Note that this is not supposed to be a full-fledged debugger. A few commands
166             are provided to aid you in finding out what went awry. See
167             L<Devel::ebug> if you're looking for a serious debugger.
168              
169             =over 4
170              
171             =item * :u
172              
173             Moves one frame up in the stack.
174              
175             =item * :d
176              
177             Moves one frame down in the stack.
178              
179             =item * :top
180              
181             Moves to the top frame of the stack.
182              
183             =item * :bottom
184              
185             Moves to the bottom frame of the stack.
186              
187             =item * :t
188              
189             Redisplay the stack trace.
190              
191             =item * :e
192              
193             Display the current lexical environment.
194              
195             =item * :l
196              
197             List eleven lines of source code of the current frame.
198              
199             =item * :q
200              
201             Close the REPL. (C<^D> also works)
202              
203             =back
204              
205             =head1 VARIABLES
206              
207             =over 4
208              
209             =item * $_REPL
210              
211             This represents the Devel::REPL object.
212              
213             =item * $_a
214              
215             This represents the arguments passed to the subroutine at the current frame in
216             the call stack. Modifications are ignored (how would that work anyway?
217             Re-invoke the sub?)
218              
219             =back
220              
221             =head1 CAVEATS
222              
223             Dynamic scope probably produces unexpected results. I don't see any easy (or
224             even difficult!) solution to this. Therefore it's a caveat and not a bug. :)
225              
226             =head1 SEE ALSO
227              
228             L<Devel::REPL>, L<Devel::ebug>, L<Enbugger>, L<CGI::Inspect>
229              
230             =head1 AUTHOR
231              
232             Shawn M Moore, C<< <sartak at gmail.com> >>
233              
234             =head1 BUGS
235              
236             Please report any bugs or feature requests to
237             C<bug-carp-repl at rt.cpan.org>, or through the web interface at
238             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Carp-REPL>.
239              
240             =head1 ACKNOWLEDGEMENTS
241              
242             Thanks to Nelson Elhage and Jesse Vincent for the idea.
243              
244             Thanks to Matt Trout and Stevan Little for their advice.
245              
246             =head1 COPYRIGHT & LICENSE
247              
248             Copyright 2007-2008 Best Practical Solutions.
249              
250             This program is free software; you can redistribute it and/or modify it
251             under the same terms as Perl itself.
252              
253             =cut
254