Search code examples
read-eval-print-loopraku

Perl6 REPL usage


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.


Solution

  • 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;
    }