we need a .gitignore file here
[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
bb125cf2 8our $VERSION = '1.003017';
afe61f9c 9
10with 'MooseX::Object::Pluggable';
11
e22aa835 12use Devel::REPL::Error;
13
afe61f9c 14has 'term' => (
b595a818 15 is => 'rw',
afe61f9c 16 default => sub { Term::ReadLine->new('Perl REPL') }
17);
18
19has 'prompt' => (
b595a818 20 is => 'rw',
afe61f9c 21 default => sub { '$ ' }
22);
23
24has 'out_fh' => (
b595a818 25 is => 'rw',
26 lazy => 1,
afe61f9c 27 default => sub { shift->term->OUT || \*STDOUT; }
28);
29
57719095 30has 'exit_repl' => (
b595a818 31 is => 'rw',
57719095 32 default => sub { 0 }
33);
34
afe61f9c 35sub run {
36 my ($self) = @_;
e22aa835 37 while ($self->run_once_safely) {
57719095 38 # keep looping unless we want to exit REPL
39 last if $self->exit_repl;
afe61f9c 40 }
41}
42
e22aa835 43sub run_once_safely {
44 my ($self, @args) = @_;
45
46 my $ret = eval { $self->run_once(@args) };
47
48 if ($@) {
49 my $error = $@;
50 eval { $self->print("Error! - $error\n"); };
51 return 1;
52 } else {
53 return $ret;
54 }
55}
56
afe61f9c 57sub run_once {
58 my ($self) = @_;
e22aa835 59
afe61f9c 60 my $line = $self->read;
57719095 61 return unless defined($line); # undefined value == EOF
e22aa835 62
63 my @ret = $self->formatted_eval($line);
64
57719095 65 $self->print(@ret) unless $self->exit_repl;
e22aa835 66
afe61f9c 67 return 1;
68}
69
e22aa835 70sub formatted_eval {
71 my ( $self, @args ) = @_;
72
73 my @ret = $self->eval(@args);
74
75 return $self->format(@ret);
76}
77
78sub format {
79 my ( $self, @stuff ) = @_;
80
c3bbf326 81 if ( $self->is_error($stuff[0]) ) {
e22aa835 82 return $self->format_error(@stuff);
83 } else {
84 return $self->format_result(@stuff);
85 }
86}
87
88sub format_result {
89 my ( $self, @stuff ) = @_;
90
91 return @stuff;
92}
93
94sub format_error {
95 my ( $self, $error ) = @_;
96 return $error->stringify;
97}
98
c3bbf326 99sub is_error {
100 my ( $self, $thingy ) = @_;
101 blessed($thingy) and $thingy->isa("Devel::REPL::Error");
102}
103
afe61f9c 104sub read {
105 my ($self) = @_;
106 return $self->term->readline($self->prompt);
107}
108
911a1c24 109sub eval {
110 my ($self, $line) = @_;
c3bbf326 111 my $compiled = $self->compile($line);
112 return $compiled unless defined($compiled) and not $self->is_error($compiled);
113 return $self->execute($compiled);
911a1c24 114}
115
116sub compile {
e22aa835 117 my ( $_REPL, @args ) = @_;
118 my $compiled = eval $_REPL->wrap_as_sub(@args);
c3bbf326 119 return $_REPL->error_return("Compile error", $@) if $@;
911a1c24 120 return $compiled;
121}
122
123sub wrap_as_sub {
e22aa835 124 my ($self, $line, %args) = @_;
125 return qq!sub {\n!. ( $args{no_mangling} ? $line : $self->mangle_line($line) ).qq!\n}\n!;
911a1c24 126}
127
128sub mangle_line {
129 my ($self, $line) = @_;
130 return $line;
131}
132
afe61f9c 133sub execute {
48ddfeae 134 my ($self, $to_exec, @args) = @_;
135 my @ret = eval { $to_exec->(@args) };
136 return $self->error_return("Runtime error", $@) if $@;
afe61f9c 137 return @ret;
138}
139
911a1c24 140sub error_return {
141 my ($self, $type, $error) = @_;
e22aa835 142 return Devel::REPL::Error->new( type => $type, message => $error );
911a1c24 143}
144
afe61f9c 145sub print {
146 my ($self, @ret) = @_;
147 my $fh = $self->out_fh;
59aedffc 148 no warnings 'uninitialized';
afe61f9c 149 print $fh "@ret";
a66625d6 150 print $fh "\n" if $self->term->ReadLine =~ /Gnu/;
afe61f9c 151}
152
59aedffc 153=head1 NAME
154
155Devel::REPL - a modern perl interactive shell
156
157=head1 SYNOPSIS
158
159 my $repl = Devel::REPL->new;
160 $repl->load_plugin($_) for qw(History LexEnv);
161 $repl->run
162
163Alternatively, use the 're.pl' script installed with the distribution
164
950232b2 165 system$ re.pl
166
408564af 167=head1 DESCRIPTION
168
169This is an interactive shell for Perl, commonly known as a REPL - Read,
170Evaluate, Print, Loop. The shell provides for rapid development or testing
171of code without the need to create a temporary source code file.
172
173Through a plugin system, many features are available on demand. You can also
174tailor the environment through the use of profiles and run control files, for
175example to pre-load certain Perl modules when working on a particular project.
176
177=head1 USAGE
178
179To start a shell, follow one of the examples in the L</"SYNOPSIS"> above.
180
181Once running, the shell accepts and will attempt to execute any code given. If
182the code executes successfully you'll be shown the result, otherwise an error
183message will be returned. Here are a few examples:
184
185 $_ print "Hello, world!\n"
186 Hello, world!
187 1
188 $_ nosuchfunction
189 Compile error: Bareword "nosuchfunction" not allowed while "strict subs" in use at (eval 130) line 5.
20d9434d 190
191 $_
408564af 192
193In the first example above you see the output of the command (C<Hello,
194world!>), if any, and then the return value of the statement (C<1>). Following
195that example, an error is returned when the execution of some code fails.
196
197Note that the lack of semicolon on the end is not a mistake - the code is
198run inside a Block structure (to protect the REPL in case the code blows up),
199which means a single statement doesn't require the semicolon. You can add one
200if you like, though.
201
6aa58492 202If you followed the first example in the L</"SYNOPSIS"> above, you'll have the
408564af 203History and LexEnv plugins loaded (and there are many more available).
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
249If the filename happens to contain a forwardslash, then it's used absolutely,
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
263A default profile ships with C<Devel::REPL>; it loads the following plugins:
264
265=over 4
266
267=item *
268
269L<Devel::REPL::Plugin::History>
270
271=item *
272
273L<Devel::REPL::Plugin::LexEnv>
274
275=item *
276
277L<Devel::REPL::Plugin::DDS>
278
279=item *
280
281L<Devel::REPL::Plugin::Packages>
282
283=item *
284
285L<Devel::REPL::Plugin::Commands>
286
287=item *
288
289L<Devel::REPL::Plugin::MultiLine::PPI>
290
071c41fa 291=item *
292
293L<Devel::REPL::Plugin::Colors>
294
295=item *
296
297L<Devel::REPL::Plugin::Completion>
298
299=item *
300
301L<Devel::REPL::Plugin::CompletionDriver::INC>
302
303=item *
304
305L<Devel::REPL::Plugin::CompletionDriver::LexEnv>
306
307=item *
308
309L<Devel::REPL::Plugin::CompletionDriver::Keywords>
310
311=item *
312
313L<Devel::REPL::Plugin::CompletionDriver::Methods>
314
315=item *
316
317L<Devel::REPL::Plugin::ReadlineHistory>
318
408564af 319=back
320
321=head2 Plugins
322
323Plugins are a way to add funcionality to the REPL shell, and take advantage of
324C<Devel::REPL> being based on the L<Moose> object system for Perl 5. This
325means it's simple to 'hook into' many steps of the R-E-P-L process. Plugins
326can change the way commands are interpreted, or the way their results are
327output, or even add commands to the shell environment.
328
329A number of plugins ship with C<Devel::REPL>, and more are available on the
330CPAN. Some of the shipped plugins are loaded in the default profile, mentioned
cfb85b27 331above. These plugins can be loaded in your C<< $HOME/.re.pl/repl.rc >> like:
332
333 load_plugin qw( CompletionDriver::Global DumpHistory );
408564af 334
335Writing your own plugins is not difficult, and is discussed in the
336L<Devel::REPL::Plugin> manual page, along with links to the manual pages of
337all the plugins shipped with C<Devel::REPL>.
338
339=head2 The REPL shell object
340
341From time to time you'll want to interact with or manipulate the
342C<Devel::REPL> shell object itself; that is, the instance of the shell you're
343currently running.
344
345The object is always available through the C<$_REPL> variable. One common
346requirement is to load an additional plugin, after your profile and run
347control files have already been executed:
348
349 $_ $_REPL->load_plugin('Timing');
350 1
351 $_ print "Hello again, world!\n"
352 Hello again, world!
353 Took 0.00148296356201172 seconds.
354 1
355 $_
356
357=head1 REQUIREMENTS
358
359In addition to the contents of the standard Perl distribution, you will need
360the following:
361
362=over 4
363
364=item *
365
73d11b24 366L<Moose> >= 0.74
6aa58492 367
368=item *
369
370L<MooseX::Object::Pluggable> >= 0.0009
408564af 371
372=item *
373
73d11b24 374L<MooseX::Getopt> >= 0.18
408564af 375
376=item *
377
aa8b7647 378L<namespace::autoclean>
408564af 379
380=item *
381
382L<File::HomeDir>
383
384=item *
385
ab213f1f 386L<Task::Weaken>
387
73d11b24 388=item *
389
390L<B::Concise>
391
392=item *
393
394L<Term::ANSIColor>
395
396=item *
397
398L<Devel::Peek>
399
ab213f1f 400=back
401
402Optionally, some plugins if installed will require the following modules:
403
404=over 4
405
406=item *
407
408L<PPI>
408564af 409
410=item *
411
6aa58492 412L<Data::Dump::Streamer>
408564af 413
414=item *
415
73d11b24 416L<Data::Dumper::Concise>
417
418=item *
419
ab213f1f 420L<File::Next>
408564af 421
422=item *
423
73d11b24 424L<Sys::SigAction>
425
426=item *
427
408564af 428L<B::Keywords>
429
430=item *
431
ab213f1f 432L<Lexical::Persistence>
408564af 433
434=item *
435
436L<App::Nopaste>
437
ab213f1f 438=item *
439
440L<Module::Refresh>
441
408564af 442=back
443
59aedffc 444=head1 AUTHOR
445
446Matt S Trout - mst (at) shadowcatsystems.co.uk (L<http://www.shadowcatsystems.co.uk/>)
447
c1d5d500 448=head1 CONTRIBUTORS
449
450=over 4
451
452=item Stevan Little - stevan (at) iinteractive.com
453
454=item Alexis Sukrieh - sukria+perl (at) sukria.net
455
456=item epitaph
457
458=item mgrimes - mgrimes (at) cpan dot org
459
460=item Shawn M Moore - sartak (at) gmail.com
461
ab213f1f 462=item Oliver Gorwits - oliver on irc.perl.org
6aa58492 463
da4881b1 464=item Andrew Moore - C<< <amoore@cpan.org> >>
465
88d6bf36 466=item Norbert Buchmuller C<< <norbi@nix.hu> >>
467
d13037d5 468=item Dave Houston C<< <dhouston@cpan.org> >>
469
73d11b24 470=item Chris Marshall
471
c1d5d500 472=back
473
59aedffc 474=head1 LICENSE
475
476This library is free software under the same terms as perl itself
477
478=cut
479
afe61f9c 4801;