File Coverage

blib/lib/Continuity/REPL.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1             package Continuity::REPL;
2              
3             our $VERSION = '0.01';
4              
5             =head1 NAME
6              
7             Continuity::REPL - Use a Devel::REPL on a Continuity server
8              
9             =head1 SYNOPSYS
10              
11             use strict;
12             use Continuity;
13             use Continuity::REPL;
14              
15             use vars qw( $repl $server );
16              
17             $repl = Continuity::REPL->new;
18             $server = Continuity->new( port => 8080 );
19             $server->loop;
20              
21             sub main {
22             my $request = shift;
23             my $count = 0;
24             while(1) {
25             $count++;
26             $request->print("Count: $count");
27             $request->next;
28             }
29             }
30              
31             The command line interaction looks like this:
32              
33             main:001:0> $server
34             $Continuity1 = Continuity=HASH(0x86468c8);
35              
36             main:002:0> $server->{mapper}->{sessions}
37             $HASH1 = {
38             19392613106888830468 => Coro::Channel=ARRAY(0x8d82038),
39             58979072056380208100 => Coro::Channel=ARRAY(0x8d78890)
40             };
41              
42             main:003:0> Coro::State::list()
43             $ARRAY1 = [
44             Coro=HASH(0x8d82208),
45             Coro=HASH(0x8d78aa0),
46             Coro=HASH(0x8d38b98),
47             Coro=HASH(0x8d38a38),
48             Coro=HASH(0x8b99248),
49             Coro=HASH(0x825d6c8),
50             Coro=HASH(0x81d7568),
51             Coro=HASH(0x81d7518),
52             Coro=HASH(0x81d7448)
53             ];
54              
55             =head1 DESCRIPTION
56              
57             This provides a Devel::REPL shell for Continuity applications.
58              
59             For now it is just amusing, but it will become useful once it can run the shell
60             within the context of individual sessions. Then it might be a nice diagnostic
61             or perhaps even development tool. Heck... maybe we can throw in a web interface
62             to it...
63              
64             Also, this library forces the PERL_RL environment variable to 'Perl' since I
65             haven't been able to figure out how to hack Term::ReadLine::Gnu yet.
66              
67             =cut
68              
69 1     1   45350 use Moose;
  1         861857  
  1         11  
70              
71             # For now we'll force Term::ReadLine::Perl since GNU doesn't work here
72 1     1   7834 BEGIN { $ENV{PERL_RL} = 'Perl' }
73              
74 1     1   2522 use Devel::REPL;
  1         133605  
  1         44  
75 1     1   562 use Coro;
  0            
  0            
76             use Coro::Event;
77             use Term::ReadLine::readline;
78              
79             has repl => (is => 'rw');
80              
81             {
82             package readline;
83              
84             no warnings 'redefine';
85             sub rl_getc {
86             my $key;
87             $Term::ReadLine::Perl::term->Tk_loop
88             if $Term::ReadLine::toloop && defined &Tk::DoOneEvent;
89             my $timer = Coro::Event->timer(interval => 0);
90             until($key = Term::ReadKey::ReadKey(-1, $readline::term_IN)) {
91             $timer->next;
92             }
93             }
94              
95             $readline::rl_getc = \&rl_getc;
96             }
97              
98              
99             # Someday maybe something like this will work for the GNU backend
100             # $repl->term->{getc_function} = sub {
101             # print STDERR "Here in getc!\n";
102             # my $timer = Coro::Event->timer(interval => 0);
103             # $timer->next;
104             # my $FILE = $repl->term->{instream};
105             # # print STDERR "file: $FILE\n";
106             # return Term::ReadLine::Gnu::XS::rl_getc($FILE);
107             # };
108              
109             =head1 METHODS
110              
111             =head2 $c_repl = Continuity::REPL->new( repl => $repl );
112              
113             Create and start a new REPL on the command line. Optionally pass your own Devel::REPL object. If you don't pass in $repl, a default is created.
114              
115             =cut
116              
117             sub BUILD {
118             my $self = shift;
119             unless($self->repl) {
120             $self->repl( $self->default_repl );
121             }
122             my $timer = Coro::Event->timer(interval => 0 );
123             async {
124             while ($timer->next) {
125             $self->repl->run_once;
126             }
127             };
128             return $self;
129             }
130              
131             =head2 default_repl
132              
133             This internal method creates the default REPL if one isn't specified.
134              
135             =cut
136              
137             sub default_repl {
138             my $self = shift;
139              
140             my $repl = Devel::REPL->new;
141             $repl->load_plugin($_) for qw(
142             History
143             LexEnv
144             Completion CompletionDriver::LexEnv
145             CompletionDriver::Keywords
146             Colors MultiLine::PPI
147             FancyPrompt
148             DDS Refresh Interrupt Packages
149             ShowClass
150             );
151              
152             $repl->fancy_prompt(sub {
153             my $self = shift;
154             sprintf '%s:%03d%s> ',
155             $self->can('current_package') ? $self->current_package : 'main',
156             $self->lines_read,
157             $self->can('line_depth') ? ':' . $self->line_depth : '';
158             });
159              
160             $repl->fancy_continuation_prompt(sub {
161             my $self = shift;
162             my $pkg = $self->can('current_package') ? $self->current_package : 'main';
163             $pkg =~ s/./ /g;
164             sprintf '%s %s* ',
165             $pkg,
166             $self->lines_read,
167             $self->can('line_depth') ? $self->line_depth : '';
168             });
169              
170             $repl->current_package('main');
171              
172             return $repl;
173             }
174              
175             =head1 SEE ALSO
176              
177             L<Continuity>, L<Devel::REPL>, L<Coro::Debug>
178              
179             =head1 AUTHOR
180              
181             Brock Wilcox <awwaiid@thelackthereof.org> - http://thelackthereof.org/
182              
183             =head1 COPYRIGHT
184              
185             Copyright (c) 2008 Brock Wilcox <awwaiid@thelackthereof.org>. All rights
186             reserved. This program is free software; you can redistribute it and/or modify
187             it under the same terms as Perl 5.10 or later.
188              
189             =cut
190              
191             1;
192