簡體   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