繁体   English   中英

如何从Clojure命令行应用程序中放入一个repl?

[英]How to drop into a repl from within a Clojure command line application?

我正在编写一个Clojure CLI应用程序,我想允许给它一个命令,该命令会将人们放入clojure.main REPL中。

有人知道我该怎么做吗? 我的努力没有取得成果。

编辑:

我的CLI接受管道输入,这使我的问题变得更糟。 这是我想要工作的示例:

(ns playground.core
  (:gen-class))

(defn -main
  [& args]
  (with-open [r (io/reader *in*)]
    (doseq [line (line-seq r)]
      (println line)))
;; Drop in repl after having read the input and printed its content)

然后我这样称呼它:

cat ./somefile.txt | lein trampoline run

您可以从程序中调用clojure.main/repl ,它将开始侦听stdin并对其进行“替换” ;-)此时,repl将开始

user> (clojure.main/repl)

然后我输入终端(+ 1 2 3)

user=> 6
user=> 

所以我在一个repl中有一个repl来模拟使用您程序的人键入start repl命令的情况。

为使人类友好的repl体验, rebl-readline项目为调用clojure.main / repl增加了很多:

(rebel-readline.core/with-line-reader
  (rebel-readline.clojure.line-reader/create
    (rebel-readline.clojure.service.local/create))
  (clojure.main/repl
     :prompt (fn []) ;; prompt is handled by line-reader
     :read (rebel-readline.clojure.main/create-repl-read)))


由于您的程序实质上分为两个阶段,

  1. 永远从标准输入中读取内容,或者直到标准输入永久关闭为止。
  2. 一旦程序失效或标准输入不再可用,无论哪种情况发生,先从标准输入中读取更多信息。

您可能需要(或者也许你已经有了),打破了的事情with-open一次一些特殊的线被发送。 一旦收到它,就完全退出line-seqwith-open 然后启动repl,以便它可以获取输入文件描述符。


一旦使程序获得了对repl的输入,就可以在封闭的shell命令中解决管道问题。 cat带有一个特殊的参数- (两边的空格都没有破折号),上面写着“停在这里并从键盘上读取,直到按Crtl-d为止”

 ~ » cat a-file - | cat hello im a line from a file hello hello 

在此示例中,它从文件中读取一行,并将其传递给cat命令(用程序替换),然后从键盘上读取单词hello并打印该行(因此您在屏幕上看到了两次)

也许启动无头REPL并有两个单独的步骤可能对您有用?

第1步

启动无头REPL,等待其启动

$ lein repl :headless :host 0.0.0.0 :port 9000
nREPL server started on port 9000 on host 0.0.0.0 - nrepl://0.0.0.0:9000

第2步

在另一个shell中,使用您的命令将命令发送到REPL:

$ cat test.txt 
(def hello "Hello world!")

$ cat test.txt | lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

pipetest.core=> (def hello "Hello world!")
#'pipetest.core/hello
pipetest.core=> Bye for now!

第三步

您可以连接到REPL,在状态从上一步更改之后继续操作,但是现在您可以使用它进行交互。

$ lein repl :connect 0.0.0.0:9000
Connecting to nREPL at 0.0.0.0:9000
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-1ubuntu0.18.04.1-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

pipetest.core=> (str hello "!!!")
"Hello world!!!!"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM