Writing a perl read-eval-print loop (REPL) - part 1

Comments

[this is good]
Doesn't using Moose make it really slow?
(that was humor, btw -- Moose is great. It will run at 35 mph and knock you over. Moose > Ninja)
(1) it's a REPL. I could care less if it takes 0.01 or 0.00001 seconds to display the next line
(2) the latest Moose lets you close classes and generate inlined constructors which speed things up substantially. Maybe I'll cover "how to optimise a REPL for no good reason other than 'because I can'" for part 4 :)
This Moose has super cow powers.
I needed something like this back in early 2004, so I wrote Shell::Base, Shell::Base does almost everything you describe here, plus a bunch more things like overridable hooks for each stage, basic configfile support, integration with an external pager, and configurable completions. I probably could have given it a better name, though, since you apparently couldn't find it.

Devel::REPL could have been implemented with Shell::Base like so:

package Devel::REPL;

use strict;
use base qw(Shell::Base);

sub do_default {
my ($self, @cmd) = @_;
chomp(my $output = eval "@cmd");
return $output;
}

1;And then use it like:

perl -MShell::Base=shell -e shell

And that will put you into a REPL.
Shell::Base is actually pretty good - note I -did- find it since I mentioned Shell::Perl above but found it lacking - but it's more designed for building a command shell than a language repl so far as I can tell and I wanted overridability at fairly specific points. This will probably make more sense to you tomorrow when I post part two and you see how I'm implemented the lexical environment stuff.

Plus once I realised I was going to have to write code at all I decided I wanted to write something that had a full meta-model, which went Moosen all the way down. When I have a need for a command shell for stuff (which is probably going to happen reasonably soon, actually) I'll have another look over Shell::Base then.
[this is good]
> Except Shell::Perl uses package variables to persist data between lines (think namespaced globals)

Shell::Perl is meant to be a simple interactive way to run Perl commands. If you enter commands like:

pirl> $a = 3;
3
pirl> $b = $a + 1;
4
pirl> $c = $a + $b;
7
it is supposed to do the same as a simple script like

package Shell::Perl::sandbox;
no strict qw(vars subs);
$a = 3;
$b = $a + 1;
$c = $a + $b;

Undeclared variables end up like package variables in Shell::Perl::sandbox which is supposed to hold all these unqualified variables in the evaluated expressions. Plain simple - as (to me) the REPL should be too clever to disturb or annoy the user. (The idea to persist the environment be it lexical or a package is damn good and untouched by Shell::Perl by now.)

For the record, there is currently a branch of Shell::Perl using Shell::Base to simplify the programming.

http://iperl.googlecode.com/svn/branches/shell-base/

It has not been promoted yet to trunk because Shell::Base issues running on Windows, Cygwin, etc.


Yeah, I know what it's supposed to do.

But even my simple scripts are 100% strict and warnings clean except where -I- explicitly turn them off, and I want any code I type at the REPL to behave the exact same way - I want strict's protection against typo-ing variable names when I'm experimenting, there are generally enough variables already :)

So we're in violent agreement on "the REPL should be too clever to disturb or annoy the user", we just have different definitions of 'disturb' and 'annoy' - which is probably going to be the case to some extent between any two developers, anda large part of why I'm aiming to keep Devel::REPL itself as simple as possible and add functionality via plugins.

Since the environment of the Devel::REPL package itself has strict and warnings on that's the default for any eval that takes place and hence what happens under 'as simple as possible', but a wrapper round execute that threw 'no strict qw(vars subs);\n' onto the front of each line would be trivial so I don't see that as a disadvantage even for those who prefer to use package vars rather than lexicals.
[this is good]
Nice topic
thanks
I have found two interesting sources Fileshunt.com and Filesfinds.com and would like to give the benefit of my experience to you.

Post a comment

Already a Vox member? Sign in

mst

About Me

mst
United Kingdom

Neighborhood

Explore friends, family, friends & family, or entire neighborhood.

Archives