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