Perl6 REPL的使用方法

8

是否可以让(Rakudo)Perl6在进入REPL之前执行一些代码?就像python使用“python -i”一样。

例如,我想加载一些模块,可能读取一个侧文件并从该侧文件构建一些数据结构,然后再进入REPL,让用户使用REPL作为用户界面来完成他们需要对数据结构进行的操作。

这与从文件加载定义启动REPL类似但又不同,尽管对此问题的答案可能会满足那个问题。基本情况是,在任何程序执行结束时,解释器不会退出,而是将用户留在REPL中。除了为交互式程序提供一个漂亮的、内置的、基于Perl6的用户界面外,它还提供了一个很好的工具,用于调试其他以错误退出的代码。

编辑:

选择Zoffix的解决方案作为正确的(到目前为止),因为它是唯一满足所有要求的解决方案。希望这种能力能够被添加到编译器或语言规范中。


可能是[从文件加载定义启动REPL]的重复问题(https://dev59.com/R6Pia4cB1Zd3GeqP2rj1)。 - brian d foy
2个回答

13
您可以使用-M开关加载模块。
$ perl6 -MJSON::Tiny

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

如果您想运行其他代码,目前必须首先将其放入一个模块中。

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

To exit type 'exit' or '^D'
> $bar
42
> 

3
我在想实际上直接调用REPL代码会有多困难。那样可以像这样执行:perl6 -e '初始化代码; repl',或者甚至可以使用命令行参数,在退出之前指示返回到REPL。 - Elizabeth Mattijsen
我正在寻找的特定行为是全局命名空间具有可供REPL用户使用的填充数据结构。这就是所引用的Python行为“python -i”所实现的。 - Calcite
@JasonDoege 这就是答案的后半部分所展示的内容。如果有一个参数总是以REPL模式启动,那将会更好,这样你就可以使用“-e”来设置初始状态,正如先前对这个答案的评论所建议的那样。我确实理解我的写法可能没有Python那么漂亮和易用,但这是目前最接近的方法,而不需要大量的工作。 - Brad Gilbert
这是否允许我传入命令行参数(例如,foo将读取和解析以构建REPL用户将访问的数据结构的文件名,以及foo将用于调整其行为的标志?) - Calcite

0
我想提供Zoffix在IRC上给出的答案。它满足基本要求,但远非完美,并且使用NQP,该语言没有用户支持,也不能保证未来的"NQP API"(即“nqp::*”调用)不会发生变化而不提前通知。
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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接