8

Is it possible to have (Rakudo) Perl6 execute some code before dropping you into the REPL? Like python does with "python -i ".

For instance, I want to load up some modules and maybe read a side file and build some data structures from that side file before dropping into the REPL and letting the user do the things they need to do on the data structure, using the REPL as a user interface.

This is similar but different than Start REPL with definitions loaded from file though answers to this question might satisfy that one. The basic case is that, at the end of execution of any program, instead of exiting, the interpreter leaves the user at the REPL. Aside from providing a nifty, built-in, Perl6-based user interface for interactive programs, it also provides a good tool from which to debug code that otherwise exits with an error.

edit:

Selecting Zoffix's solution as the correct (so far) one as it is the only one that satisfies all requirements as stated. Here's hoping this capability gets added to the compiler or language spec.

Calcite
  • 131
  • 1
  • 6
  • Possible duplicate of [Start REPL with definitions loaded from file](https://stackoverflow.com/questions/45290418/start-repl-with-definitions-loaded-from-file) – brian d foy May 02 '18 at 13:05

2 Answers2

13

You can load modules with the -M switch.

$ perl6 -MJSON::Tiny

To exit type 'exit' or '^D'
> to-json Array.new: 1,2,3.Str
[ 1, 2, "3" ]
> 

If you want to run other code, currently you have to put it into a module first.

$ mkdir lib
$ echo 'our $bar = 42' > lib/foo.pm6
$ perl6 -Ilib -Mfoo

To exit type 'exit' or '^D'
> $bar
42
> 
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • 3
    I wonder how difficult it would be to actually directly invoke the REPL code. That would allow something like `perl6 -e 'init code; repl'` or maybe even a command line parameter that would indicate falling back to the REPL just before exit. – Elizabeth Mattijsen May 02 '18 at 10:14
  • The particular behavior I am looking for is the global namespace to have populated data-structures available to the REPL user. That is what the referenced Python behavior "python -i" accomplishes. – Calcite May 03 '18 at 01:48
  • @JasonDoege That is what the second half of the answer shows. It would be better if there was an argument that would always start it in REPL mode so that you could use `-e` to setup the initial state, just like the previous comment on this answer suggests. I do understand that what I have written is likely not as nice and easy to use as what Python has, but it is the closest currently without going to a lot of work. – Brad Gilbert May 03 '18 at 15:01
  • Does that let me pass in command line arguments (such as a filename that foo will read and parse to build the data structure the REPL user will access and flags that foo will use to adjust its behavior?) – Calcite May 04 '18 at 14:05
0

I'd like to provide an answer that Zoffix gave on IRC. It satisfies the basic requirement but is far from pretty and it uses NQP for which there is no user support nor is the NQP API ( "nqp::*" calls ) guaranteed for the future and can change without warning.

replify 「
  say 'Hello to your custom REPL! Type `say $a` to print the secret variable';
  my $a = "The value is {rand}";
」;

sub replify (Str:D \pre-code = '') {
    use nqp;
    my %adverbs; # command line args like --MFoo
    my \r := REPL.new: nqp::getcomp('perl6'), %adverbs;
    my \enc := %adverbs<encoding>:v.Str;
    enc && enc ne 'fixed_8' && $*IN.set-encoding: enc;

    my $*CTXSAVE := r;
    my $*MAIN_CTX;
    pre-code and r.repl-eval: pre-code, $, :outer_ctx(nqp::getattr(r, REPL, '$!save_ctx')),
      |%adverbs;
    $*MAIN_CTX and nqp::bindattr(r, REPL, '$!save_ctx', $*MAIN_CTX);

    r.repl-loop: :interactive, |%adverbs;
}
Calcite
  • 131
  • 1
  • 6