I no longer use this plugin in my bundle
[p5sagit/Devel-REPL.git] / lib / Devel / REPL.pm
CommitLineData
afe61f9c 1package Devel::REPL;
2
54beb05d 3our $VERSION = '1.003027';
4
afe61f9c 5use Term::ReadLine;
6use Moose;
aa8b7647 7use namespace::autoclean;
089a0c4e 8use 5.008001; # backwards compat, doesn't warn like 5.8.1
59aedffc 9
afe61f9c 10with 'MooseX::Object::Pluggable';
11
e22aa835 12use Devel::REPL::Error;
13
afe61f9c 14has 'term' => (
b595a818 15 is => 'rw',
2df2b90e 16 lazy => 1,
afe61f9c 17 default => sub { Term::ReadLine->new('Perl REPL') }
18);
19
20has 'prompt' => (
b595a818 21 is => 'rw',
afe61f9c 22 default => sub { '$ ' }
23);
24
25has 'out_fh' => (
b595a818 26 is => 'rw',
27 lazy => 1,
afe61f9c 28 default => sub { shift->term->OUT || \*STDOUT; }
29);
30
57719095 31has 'exit_repl' => (
b595a818 32 is => 'rw',
57719095 33 default => sub { 0 }
34);
35
afe61f9c 36sub run {
37 my ($self) = @_;
e22aa835 38 while ($self->run_once_safely) {
57719095 39 # keep looping unless we want to exit REPL
40 last if $self->exit_repl;
afe61f9c 41 }
42}
43
e22aa835 44sub run_once_safely {
45 my ($self, @args) = @_;
46
47 my $ret = eval { $self->run_once(@args) };
48
49 if ($@) {
50 my $error = $@;
51 eval { $self->print("Error! - $error\n"); };
52 return 1;
53 } else {
54 return $ret;
55 }
56}
57
afe61f9c 58sub run_once {
59 my ($self) = @_;
e22aa835 60
afe61f9c 61 my $line = $self->read;
57719095 62 return unless defined($line); # undefined value == EOF
e22aa835 63
64 my @ret = $self->formatted_eval($line);
65
57719095 66 $self->print(@ret) unless $self->exit_repl;
e22aa835 67
afe61f9c 68 return 1;
69}
70
e22aa835 71sub formatted_eval {
72 my ( $self, @args ) = @_;
73
74 my @ret = $self->eval(@args);
75
76 return $self->format(@ret);
77}
78
79sub format {
80 my ( $self, @stuff ) = @_;
81
c3bbf326 82 if ( $self->is_error($stuff[0]) ) {
e22aa835 83 return $self->format_error(@stuff);
84 } else {
85 return $self->format_result(@stuff);
86 }
87}
88
89sub format_result {
90 my ( $self, @stuff ) = @_;
91
92 return @stuff;
93}
94
95sub format_error {
96 my ( $self, $error ) = @_;
97 return $error->stringify;
98}
99
c3bbf326 100sub is_error {
101 my ( $self, $thingy ) = @_;
102 blessed($thingy) and $thingy->isa("Devel::REPL::Error");
103}
104
afe61f9c 105sub read {
106 my ($self) = @_;
107 return $self->term->readline($self->prompt);
108}
109
911a1c24 110sub eval {
111 my ($self, $line) = @_;
c3bbf326 112 my $compiled = $self->compile($line);
113 return $compiled unless defined($compiled) and not $self->is_error($compiled);
114 return $self->execute($compiled);
911a1c24 115}
116
117sub compile {
e22aa835 118 my ( $_REPL, @args ) = @_;
119 my $compiled = eval $_REPL->wrap_as_sub(@args);
c3bbf326 120 return $_REPL->error_return("Compile error", $@) if $@;
911a1c24 121 return $compiled;
122}
123
124sub wrap_as_sub {
e22aa835 125 my ($self, $line, %args) = @_;
126 return qq!sub {\n!. ( $args{no_mangling} ? $line : $self->mangle_line($line) ).qq!\n}\n!;
911a1c24 127}
128
129sub mangle_line {
130 my ($self, $line) = @_;
131 return $line;
132}
133
afe61f9c 134sub execute {
48ddfeae 135 my ($self, $to_exec, @args) = @_;
136 my @ret = eval { $to_exec->(@args) };
137 return $self->error_return("Runtime error", $@) if $@;
afe61f9c 138 return @ret;
139}
140
911a1c24 141sub error_return {
142 my ($self, $type, $error) = @_;
e22aa835 143 return Devel::REPL::Error->new( type => $type, message => $error );
911a1c24 144}
145
afe61f9c 146sub print {
147 my ($self, @ret) = @_;
148 my $fh = $self->out_fh;
59aedffc 149 no warnings 'uninitialized';
afe61f9c 150 print $fh "@ret";
a66625d6 151 print $fh "\n" if $self->term->ReadLine =~ /Gnu/;
afe61f9c 152}
153
59aedffc 154=head1 NAME
155
eb7716dc 156Devel::REPL - A modern perl interactive shell
59aedffc 157
158=head1 SYNOPSIS
159
160 my $repl = Devel::REPL->new;
161 $repl->load_plugin($_) for qw(History LexEnv);
162 $repl->run
163
164Alternatively, use the 're.pl' script installed with the distribution
165
950232b2 166 system$ re.pl
167
408564af 168=head1 DESCRIPTION
169
170This is an interactive shell for Perl, commonly known as a REPL - Read,
171Evaluate, Print, Loop. The shell provides for rapid development or testing
172of code without the need to create a temporary source code file.
173
174Through a plugin system, many features are available on demand. You can also
175tailor the environment through the use of profiles and run control files, for
176example to pre-load certain Perl modules when working on a particular project.
177
178=head1 USAGE
179
180To start a shell, follow one of the examples in the L</"SYNOPSIS"> above.
181
182Once running, the shell accepts and will attempt to execute any code given. If
183the code executes successfully you'll be shown the result, otherwise an error
184message will be returned. Here are a few examples:
185
186 $_ print "Hello, world!\n"
187 Hello, world!
188 1
189 $_ nosuchfunction
190 Compile error: Bareword "nosuchfunction" not allowed while "strict subs" in use at (eval 130) line 5.
20d9434d 191
192 $_
408564af 193
194In the first example above you see the output of the command (C<Hello,
195world!>), if any, and then the return value of the statement (C<1>). Following
196that example, an error is returned when the execution of some code fails.
197
198Note that the lack of semicolon on the end is not a mistake - the code is
199run inside a Block structure (to protect the REPL in case the code blows up),
200which means a single statement doesn't require the semicolon. You can add one
201if you like, though.
202
6aa58492 203If you followed the first example in the L</"SYNOPSIS"> above, you'll have the
8d5343b5 204L<History|Devel::REPL::Plugin::History> and L<LexEnv|Devel::REPL::Plugin::LexEnv>
205plugins loaded (and there are many more available).
408564af 206Although the shell might support "up-arrow" history, the History plugin adds
207"bang" history to that so you can re-execute chosen commands (with e.g.
208C<!53>). The LexEnv plugin ensures that lexical variables declared with the
209C<my> keyword will automatically persist between statements executed in the
210REPL shell.
211
212When you C<use> any Perl module, the C<import()> will work as expected - the
213exported functions from that module are available for immediate use:
214
215 $_ carp "I'm dieeeing!\n"
216 String found where operator expected at (eval 129) line 5, near "carp "I'm dieeeing!\n""
217 (Do you need to predeclare carp?)
218 Compile error: syntax error at (eval 129) line 5, near "carp "I'm dieeeing!\n""
219 BEGIN not safe after errors--compilation aborted at (eval 129) line 5.
20d9434d 220
221 $_ use Carp
222
408564af 223 $_ carp "I'm dieeeing!\n"
224 I'm dieeeing!
225 at /usr/share/perl5/Lexical/Persistence.pm line 327
226 1
20d9434d 227 $_
408564af 228
73d11b24 229To quit from the shell, hit C<Ctrl+D> or C<Ctrl+C>.
230
231 MSWin32 NOTE: control keys won't work if TERM=dumb
232 because readline functionality will be disabled.
233
408564af 234
235=head2 Run Control Files
236
237For particular projects you might well end up running the same commands each
238time the REPL shell starts up - loading Perl modules, setting configuration,
239and so on. A run control file lets you have this done automatically, and you
240can have multiple files for different projects.
241
242By default the C<re.pl> program looks for C<< $HOME/.re.pl/repl.rc >>, and
243runs whatever code is in there as if you had entered it at the REPL shell
244yourself.
245
246To set a new run control file that's also in that directory, pass it as a
247filename like so:
248
249 system$ re.pl --rcfile myproject.pc
250
0e0d2539 251If the filename happens to contain a forward slash, then it's used absolutely,
408564af 252or realive to the current working directory:
253
254 system$ re.pl --rcfile /path/to/my/project/repl.rc
255
256Within the run control file you might want to load plugins. This is covered in
257L</"The REPL shell object"> section, below.
258
259=head2 Profiles
260
261To allow for the sharing of run control files, you can fashion them into a
262Perl module for distribution (perhaps via the CPAN). For more information on
263this feature, please see the L<Devel::REPL::Profile> manual page.
264
e72070d7 265A C<Standard> profile ships with C<Devel::REPL>; it loads the following plugins
266(note that some of these require optional features -- or you can also use the
267C<Minimal> profile):
408564af 268
269=over 4
270
271=item *
272
273L<Devel::REPL::Plugin::History>
274
275=item *
276
277L<Devel::REPL::Plugin::LexEnv>
278
279=item *
280
281L<Devel::REPL::Plugin::DDS>
282
283=item *
284
285L<Devel::REPL::Plugin::Packages>
286
287=item *
288
289L<Devel::REPL::Plugin::Commands>
290
291=item *
292
293L<Devel::REPL::Plugin::MultiLine::PPI>
294
071c41fa 295=item *
296
297L<Devel::REPL::Plugin::Colors>
298
299=item *
300
301L<Devel::REPL::Plugin::Completion>
302
303=item *
304
305L<Devel::REPL::Plugin::CompletionDriver::INC>
306
307=item *
308
309L<Devel::REPL::Plugin::CompletionDriver::LexEnv>
310
311=item *
312
313L<Devel::REPL::Plugin::CompletionDriver::Keywords>
314
315=item *
316
317L<Devel::REPL::Plugin::CompletionDriver::Methods>
318
319=item *
320
321L<Devel::REPL::Plugin::ReadlineHistory>
322
408564af 323=back
324
325=head2 Plugins
326
0e0d2539 327Plugins are a way to add functionality to the REPL shell, and take advantage of
408564af 328C<Devel::REPL> being based on the L<Moose> object system for Perl 5. This
329means it's simple to 'hook into' many steps of the R-E-P-L process. Plugins
330can change the way commands are interpreted, or the way their results are
331output, or even add commands to the shell environment.
332
333A number of plugins ship with C<Devel::REPL>, and more are available on the
334CPAN. Some of the shipped plugins are loaded in the default profile, mentioned
8d5343b5 335above. These plugins can be loaded in your F< $HOME/.re.pl/repl.rc > like:
cfb85b27 336
337 load_plugin qw( CompletionDriver::Global DumpHistory );
408564af 338
339Writing your own plugins is not difficult, and is discussed in the
340L<Devel::REPL::Plugin> manual page, along with links to the manual pages of
341all the plugins shipped with C<Devel::REPL>.
342
343=head2 The REPL shell object
344
345From time to time you'll want to interact with or manipulate the
346C<Devel::REPL> shell object itself; that is, the instance of the shell you're
347currently running.
348
349The object is always available through the C<$_REPL> variable. One common
350requirement is to load an additional plugin, after your profile and run
351control files have already been executed:
352
353 $_ $_REPL->load_plugin('Timing');
354 1
355 $_ print "Hello again, world!\n"
356 Hello again, world!
357 Took 0.00148296356201172 seconds.
358 1
359 $_
360
e72070d7 361=head1 OPTIONAL FEATURES
408564af 362
e72070d7 363In addition to the prerequisites declared in this distribution, which should be automatically installed by your L<CPAN> client, there are a number of optional features, used by
364additional plugins. You can install any of these features by installing this
365distribution interactively (e.g. C<cpanm --interactive Devel::REPL>).
408564af 366
e72070d7 367=for comment I hope to automatically generate this data via a Pod::Weaver section
ab213f1f 368
369=over 4
370
e72070d7 371=item * Completion plugin - extensible tab completion
ab213f1f 372
e72070d7 373=item * DDS plugin - better format results with Data::Dump::Streamer
408564af 374
e72070d7 375=item * DDC plugin - even better format results with Data::Dumper::Concise
408564af 376
e72070d7 377=item * INC completion driver - tab complete module names in use and require
408564af 378
e72070d7 379=item * Interrupt plugin - traps SIGINT to kill long-running lines
408564af 380
e72070d7 381=item * Keywords completion driver - tab complete Perl keywords and operators
73d11b24 382
e72070d7 383=item * LexEnv plugin - variables declared with "my" persist between statements
73d11b24 384
e72070d7 385=item * MultiLine::PPI plugin - continue reading lines until all blocks are closed
408564af 386
e72070d7 387=item * Nopaste plugin - upload a session\'s input and output to a Pastebin
408564af 388
e72070d7 389=item * PPI plugin - PPI dumping of Perl code
ab213f1f 390
e72070d7 391=item * Refresh plugin - automatically reload libraries with Module::Refresh
ab213f1f 392
408564af 393=back
394
59aedffc 395=head1 AUTHOR
396
397Matt S Trout - mst (at) shadowcatsystems.co.uk (L<http://www.shadowcatsystems.co.uk/>)
398
c1d5d500 399=head1 CONTRIBUTORS
400
401=over 4
402
403=item Stevan Little - stevan (at) iinteractive.com
404
405=item Alexis Sukrieh - sukria+perl (at) sukria.net
406
407=item epitaph
408
409=item mgrimes - mgrimes (at) cpan dot org
410
411=item Shawn M Moore - sartak (at) gmail.com
412
ab213f1f 413=item Oliver Gorwits - oliver on irc.perl.org
6aa58492 414
da4881b1 415=item Andrew Moore - C<< <amoore@cpan.org> >>
416
88d6bf36 417=item Norbert Buchmuller C<< <norbi@nix.hu> >>
418
d13037d5 419=item Dave Houston C<< <dhouston@cpan.org> >>
420
73d11b24 421=item Chris Marshall
422
b28cbcb7 423=item Karen Etheridge C<< <ether@cpan.org> >>
424
c1d5d500 425=back
426
59aedffc 427=head1 LICENSE
428
429This library is free software under the same terms as perl itself
430
431=cut
432
afe61f9c 4331;