fd91a91eae527760faa362ec01acf3beb093ada3
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / LexEnv.pm
1 package Devel::REPL::Plugin::LexEnv;
2
3 use Moose::Role;
4 use namespace::clean -except => [ 'meta' ];
5 use Lexical::Persistence;
6
7 with 'Devel::REPL::Plugin::FindVariable';
8
9 has 'lexical_environment' => (
10   isa => 'Lexical::Persistence',
11   is => 'rw',
12   required => 1,
13   lazy => 1,
14   default => sub { Lexical::Persistence->new }
15 );
16
17 has '_hints' => (
18   isa => "ArrayRef",
19   is => "rw",
20   predicate => '_has_hints',
21 );
22
23 around 'mangle_line' => sub {
24   my $orig = shift;
25   my ($self, @rest) = @_;
26   my $line = $self->$orig(@rest);
27   my $lp = $self->lexical_environment;
28   # Collate my declarations for all LP context vars then add '';
29   # so an empty statement doesn't return anything (with a no warnings
30   # to prevent "Useless use ..." warning)
31   return join('',
32     'BEGIN { if ( $_REPL->_has_hints ) { ( $^H, %^H ) = @{ $_REPL->_hints } } }',
33     ( map { "my $_;\n" } keys %{$lp->get_context('_')} ),
34     qq{{ no warnings 'void'; ''; }\n},
35     $line,
36     '; BEGIN { $_REPL->_hints([ $^H, %^H ]) }',
37   );
38 };
39
40 around 'execute' => sub {
41   my $orig = shift;
42   my ($self, $to_exec, @rest) = @_;
43   my $wrapped = $self->lexical_environment->wrap($to_exec);
44   return $self->$orig($wrapped, @rest);
45 };
46
47 around 'find_variable' => sub {
48   my $orig = shift;
49   my ($self, $name) = @_;
50   my $variable = $self->lexical_environment->get_context('_')->{$name};
51   return \$variable if $variable;
52   return $orig->(@_);
53 };
54
55 1;