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