keep $VERSION right in the repo
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / OutputCache.pm
1 use strict;
2 use warnings;
3 package Devel::REPL::Plugin::OutputCache;
4
5 our $VERSION = '1.003027';
6
7 use Devel::REPL::Plugin;
8 use namespace::autoclean;
9
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 __END__
56
57 =head1 NAME
58
59 Devel::REPL::Plugin::OutputCache - remember past results, _ is most recent
60
61 =head1 SYNOPSIS
62
63     > 21 / 7
64     3
65     > _ * _
66     9
67     > sub { die "later" }
68     sub { die "later" }
69     > _->()
70     Runtime error: later
71
72 =head1 DESCRIPTION
73
74 Re-using results is very useful when working in a REPL. With C<OutputCache> you
75 get C<_>, which holds the past result. The benefit is that you can build up
76 your result instead of having to type it in all at once, or store it in
77 intermediate variables. C<OutputCache> also provides
78 C<< $_REPL->output_cache >>, an array reference of all results in this session.
79
80 L<Devel::REPL> already has a similar plugin, L<Devel::REPL::Plugin::History>.
81 There are some key differences though:
82
83 =over 4
84
85 =item Input vs Output
86
87 C<History> remembers input. C<OutputCache> remembers output.
88
89 =item Munging vs Pure Perl
90
91 C<History> performs regular expressions on your input. C<OutputCache> provides
92 the C<_> sub as a hook to get the most recent result, and
93 C<< $_REPL->output_cache >> for any other results.
94
95 =item Principle of Least Surprise
96
97 C<History> will replace exclamation points in any part of the input. This is
98 problematic if you accidentally include one in a string, or in a C<not>
99 expression. C<OutputCache> uses a regular (if oddly named) subroutine so Perl
100 does the parsing -- no surprises.
101
102 =back
103
104 =head1 CAVEATS
105
106 The C<_> sub is shared across all packages. This means that if a module is
107 using the C<_> sub, then there is a conflict and you should not use this
108 plugin. For example, L<Jifty> uses the C<_> sub for localization. L<Jifty> is the
109 only known user.
110
111 =head1 SEE ALSO
112
113 C<Devel::REPL>, C<Devel::REPL::Plugin::History>
114
115 =head1 AUTHOR
116
117 Shawn M Moore, C<< <sartak at gmail dot com> >>
118
119 =head1 COPYRIGHT AND LICENSE
120
121 Copyright (C) 2007 by Shawn M Moore
122
123 This library is free software; you can redistribute it and/or modify
124 it under the same terms as Perl itself.
125
126 =cut