fd72a3613c831bd5ebd8f8c52a6b45d4942a7759
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / LexEnv.pm
1 use strict;
2 use warnings;
3 package Devel::REPL::Plugin::LexEnv;
4
5 our $VERSION = '1.003027';
6
7 use Devel::REPL::Plugin;
8 use namespace::autoclean;
9 use Lexical::Persistence;
10
11 sub BEFORE_PLUGIN {
12     my $self = shift;
13     $self->load_plugin('FindVariable');
14 }
15
16 has 'lexical_environment' => (
17   isa => 'Lexical::Persistence',
18   is => 'rw',
19   lazy => 1,
20   default => sub { Lexical::Persistence->new }
21 );
22
23 has '_hints' => (
24   isa => "ArrayRef",
25   is => "rw",
26   predicate => '_has_hints',
27 );
28
29 around 'mangle_line' => sub {
30   my $orig = shift;
31   my ($self, @rest) = @_;
32   my $line = $self->$orig(@rest);
33   my $lp = $self->lexical_environment;
34   # Collate my declarations for all LP context vars then add '';
35   # so an empty statement doesn't return anything (with a no warnings
36   # to prevent "Useless use ..." warning)
37   return join('',
38     'BEGIN { if ( $_REPL->_has_hints ) { ( $^H, %^H ) = @{ $_REPL->_hints } } }',
39     ( map { "my $_;\n" } keys %{$lp->get_context('_')} ),
40     qq{{ no warnings 'void'; ''; }\n},
41     $line,
42     '; BEGIN { $_REPL->_hints([ $^H, %^H ]) }',
43   );
44 };
45
46 around 'execute' => sub {
47   my $orig = shift;
48   my ($self, $to_exec, @rest) = @_;
49   my $wrapped = $self->lexical_environment->wrap($to_exec);
50   return $self->$orig($wrapped, @rest);
51 };
52
53 # this doesn't work! yarg. we now just check $self->can('lexical_environment')
54 # in FindVariable
55
56 #around 'find_variable' => sub {
57 #  my $orig = shift;
58 #  my ($self, $name) = @_;
59 #
60 #  return \( $self->lexical_environment->get_context('_')->{$name} )
61 #    if exists $self->lexical_environment->get_context('_')->{$name};
62 #
63 #  return $orig->(@_);
64 #};
65
66 1;
67
68 __END__
69
70 =head1 NAME
71
72 Devel::REPL::Plugin::LexEnv - Provide a lexical environment for the REPL
73
74 =head1 SYNOPSIS
75
76  # in your re.pl file:
77  use Devel::REPL;
78  my $repl = Devel::REPL->new;
79  $repl->load_plugin('LexEnv');
80
81  $repl->lexical_environment->do(<<'CODEZ');
82  use FindBin;
83  use lib "$FindBin::Bin/../lib";
84  use MyApp::Schema;
85  my $s = MyApp::Schema->connect('dbi:Pg:dbname=foo','broseph','elided');
86  CODEZ
87
88  $repl->run;
89
90  # after you run re.pl:
91  $ warn $s->resultset('User')->first->first_name # <-- note that $s works
92
93 =cut
94