File Coverage

blib/lib/Devel/REPL/Plugin/OutputCache.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1 2     2   1894 use strict;
  2         4  
  2         56  
2 2     2   9 use warnings;
  2         4  
  2         93  
3             # ABSTRACT: Remember past results, _ is most recent
4              
5             our $VERSION = '1.003029';
6              
7             use Devel::REPL::Plugin;
8 2     2   11 use namespace::autoclean;
  2         4  
  2         12  
9 2     2   8025  
  2         3  
  2         17  
10             has output_cache => (
11             is => 'rw',
12             isa => 'ArrayRef',
13             default => sub { [] },
14             lazy => 1,
15             );
16              
17             has warned_about_underscore => (
18             is => 'rw',
19             isa => 'Bool',
20             default => 0,
21             lazy => 1,
22             );
23              
24             around 'eval' => sub {
25             my $orig = shift;
26             my ($self, $line) = @_;
27              
28             my $has_underscore = *_{CODE};
29             if ($has_underscore && !$self->warned_about_underscore) {
30             warn "OutputCache: Sub _ already defined.";
31             $self->warned_about_underscore(1);
32             }
33             else {
34             # if _ is removed, then we should warn about it again if it comes back
35             $self->warned_about_underscore(0);
36             }
37              
38             # this needs to be a postfix conditional for 'local' to work
39             local *_ = sub () { $self->output_cache->[-1] } unless $has_underscore;
40              
41             my @ret;
42             if (wantarray) {
43             @ret = $self->$orig($line);
44             }
45             else {
46             $ret[0] = $self->$orig($line);
47             }
48              
49             push @{ $self->output_cache }, @ret > 1 ? \@ret : $ret[0];
50             return wantarray ? @ret : $ret[0];
51             };
52              
53             1;
54              
55              
56             =pod
57              
58             =encoding UTF-8
59              
60             =head1 NAME
61              
62             Devel::REPL::Plugin::OutputCache - Remember past results, _ is most recent
63              
64             =head1 VERSION
65              
66             version 1.003029
67              
68             =head1 SYNOPSIS
69              
70             > 21 / 7
71             3
72             > _ * _
73             9
74             > sub { die "later" }
75             sub { die "later" }
76             > _->()
77             Runtime error: later
78              
79             =head1 DESCRIPTION
80              
81             Re-using results is very useful when working in a REPL. With C<OutputCache> you
82             get C<_>, which holds the past result. The benefit is that you can build up
83             your result instead of having to type it in all at once, or store it in
84             intermediate variables. C<OutputCache> also provides
85             C<< $_REPL->output_cache >>, an array reference of all results in this session.
86              
87             L<Devel::REPL> already has a similar plugin, L<Devel::REPL::Plugin::History>.
88             There are some key differences though:
89              
90             =over 4
91              
92             =item Input vs Output
93              
94             C<History> remembers input. C<OutputCache> remembers output.
95              
96             =item Munging vs Pure Perl
97              
98             C<History> performs regular expressions on your input. C<OutputCache> provides
99             the C<_> sub as a hook to get the most recent result, and
100             C<< $_REPL->output_cache >> for any other results.
101              
102             =item Principle of Least Surprise
103              
104             C<History> will replace exclamation points in any part of the input. This is
105             problematic if you accidentally include one in a string, or in a C<not>
106             expression. C<OutputCache> uses a regular (if oddly named) subroutine so Perl
107             does the parsing -- no surprises.
108              
109             =back
110              
111             =head1 CAVEATS
112              
113             The C<_> sub is shared across all packages. This means that if a module is
114             using the C<_> sub, then there is a conflict and you should not use this
115             plugin. For example, L<Jifty> uses the C<_> sub for localization. L<Jifty> is the
116             only known user.
117              
118             =head1 SEE ALSO
119              
120             C<Devel::REPL>, C<Devel::REPL::Plugin::History>
121              
122             =head1 SUPPORT
123              
124             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Devel-REPL>
125             (or L<bug-Devel-REPL@rt.cpan.org|mailto:bug-Devel-REPL@rt.cpan.org>).
126              
127             There is also an irc channel available for users of this distribution, at
128             L<C<#devel> on C<irc.perl.org>|irc://irc.perl.org/#devel-repl>.
129              
130             =head1 AUTHOR
131              
132             Shawn M Moore, C<< <sartak at gmail dot com> >>
133              
134             =head1 COPYRIGHT AND LICENSE
135              
136             Copyright (C) 2007 by Shawn M Moore
137              
138             This library is free software; you can redistribute it and/or modify
139             it under the same terms as Perl itself.
140              
141             =cut