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