use Perl Log In
Devel::REPL: now with PPI!
There are plugins to dump output with Data::Dump::Streamer, enable tab completion of the current lexical environment and loaded modules, save input history across sessions, and more. If you dabble in other P-languages such as Python and Ruby (know thy enemy.. honest!) you'll find yourself wanting more out of Devel::REPL. Let's take the example of writing a factorial function in python:
% python
Python 2.3.5 (#1, Dec 7 2006, 14:50:51)
[GCC 4.0.1 (Apple Computer, Inc. build 5363) (+4864187)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def fact(n):
... if n < 2:
... return 1
... return n * fact(n - 1)
...
>>> fact(10)
3628800
in irb:
% irb
irb(main):001:0> def fact(n)
irb(main):002:1> if n < 2
irb(main):003:2> 1
irb(main):004:2> else
irb(main):005:2* n * fact(n-1)
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> fact 10
=> 3628800
and in Devel::REPL:
D'oh. OK, let's try again..% re.pl
$ sub fact {
Compile error: Missing right curly or square bracket at (eval 60) line
8, at end of line
syntax error at (eval 60) line 8, at EOF
% re.pl
$ sub fact { my $n = shift; return 1 if $n < 2; $n * fact($n - 1) }
$ fact 10
3628800
Well, that works in this case, but one big line of code quickly becomes unmanageable.
Recently I had the idea to use PPI to figure out if the current line of code is complete. PPI::Dumper quickly confirmed that I can detect the most important case: a PPI::Structure that doesn't have both a ->start and ->finish. Structures encompass { {nested { blocks } } }, (parentheses), [array indexing], {hash indexing}, and so on. Hopefully future versions of PPI will be able to figure out that, say, an s/// or quoted string is incomplete.
Here's what the factorial example looks like with the MultiLine::PPI plugin.
% re.pl
$ load_plugin 'MultiLine::PPI'
1
$ sub fact {
> my $n = shift;
> return 1 if $n < 2;
> $n * fact($n - 1);
> }
$ fact 10
3628800
I believe Devel::REPL is the only Perl REPL that can do this. Hooray! :)
MultiLine::PPI hasn't been CPANed yet, but you can get it (and other new plugins) from the Devel::REPL Subversion repository.
I'll continue stealing good features from irb and python.

fantastic (Score:1)
rjbs
"Only"? (Score:1)
Re: (Score:1)
Ah. I've seen Sepia before in search results, but I've never actually checked it out (seeing as how I'm a vim guy).
Interesting way to solve the same problem. Both have their strengths and weaknesses (PPI is more correct and won't run BEGIN/CHECK blocks, Sepia probably handles more cases, such as s/// and quoted strings)
Re: (Score:1)
PPI handles the two cases you want (Score:1)
Re: (Score:1)
Re: (Score:1)
What might be a better idea though, is to introduce an ->complete or ->incomplete method at the PPI::Element level and abstract the entire thing behind a nice interface.
Re: (Score:1)
That would be great. I've taken a stab at implementing it and it looks to be way over my head.