Devel::REPL::Plugin::OutputCache - remember past results, _ is most recent


Devel-REPL documentation Contained in the Devel-REPL distribution.

Index


Code Index:

NAME

Top

Devel::REPL::Plugin::OutputCache - remember past results, _ is most recent

SYNOPSIS

Top

    > 21 / 7
    3
    > _ * _
    9
    > sub { die "later" }
    sub { die "later" }
    > _->()
    Runtime error: later

DESCRIPTION

Top

Re-using results is very useful when working in a REPL. With OutputCache you get _, which holds the past result. The benefit is that you can build up your result instead of having to type it in all at once, or store it in intermediate variables. OutputCache also provides $_REPL->output_cache, an array reference of all results in this session.

Devel::REPL already has a similar plugin, Devel::REPL::Plugin::History. There are some key differences though:

Input vs Output

History remembers input. OutputCache remembers output.

Munging vs Pure Perl

History performs regular expressions on your input. OutputCache provides the _ sub as a hook to get the most recent result, and $_REPL->output_cache for any other results.

Principle of Least Surprise

History will replace exclamation points in any part of the input. This is problematic if you accidentally include one in a string, or in a not expression. OutputCache uses a regular (if oddly named) subroutine so Perl does the parsing -- no surprises.

CAVEATS

Top

The _ sub is shared across all packages. This means that if a module is using the _ sub, then there is a conflict and you should not use this plugin. For example, Jifty uses the _ sub for localization. Jifty is the only known user.

SEE ALSO

Top

Devel::REPL, Devel::REPL::Plugin::History

AUTHOR

Top

Shawn M Moore, <sartak at gmail dot com>

COPYRIGHT AND LICENSE

Top


Devel-REPL documentation Contained in the Devel-REPL distribution.

package Devel::REPL::Plugin::OutputCache;

use Devel::REPL::Plugin;
use namespace::clean -except => [ 'meta' ];

has output_cache => (
    is      => 'rw',
    isa     => 'ArrayRef',
    default => sub { [] },
    lazy    => 1,
);

has warned_about_underscore => (
    is      => 'rw',
    isa     => 'Bool',
    default => 0,
    lazy    => 1,
);

around 'eval' => sub {
    my $orig = shift;
    my ($self, $line) = @_;

    my $has_underscore = *_{CODE};
    if ($has_underscore && !$self->warned_about_underscore) {
        warn "OutputCache: Sub _ already defined.";
        $self->warned_about_underscore(1);
    }
    else {
        # if _ is removed, then we should warn about it again if it comes back
        $self->warned_about_underscore(0);
    }

    # this needs to be a postfix conditional for 'local' to work
    local *_ = sub () { $self->output_cache->[-1] } unless $has_underscore;

    my @ret;
    if (wantarray) {
        @ret = $self->$orig($line);
    }
    else {
        $ret[0] = $self->$orig($line);
    }

    push @{ $self->output_cache }, @ret > 1 ? \@ret : $ret[0];
    return wantarray ? @ret : $ret[0];
};

1;

__END__