【问题标题】:Clojure (read-line) doesn't wait for inputClojure(读取行)不等待输入
【发布时间】:2011-12-04 04:29:14
【问题描述】:

我正在用 Clojure 编写一个文本游戏。我希望玩家在控制台上输入台词,然后游戏会逐行响应。

研究表明(read-line) 是一种用于从 Clojure 中的标准输入中获取文本行的方式,但它不适用于我。

我在一个新的 Leiningen 项目中,我在 project.clj 中添加了一个 :main 子句,指向唯一的源文件:

(ns textgame.core)

(defn -main [& args]
  (println "Entering -main")
;  (flush)                      ;makes no difference if flush are commented out
  (let [input (read-line)]
    (println "ECHO:" input))
;  (flush)
  (println "Exiting -main"))

使用lein run 产生:

Entering -main
ECHO: nil
Exiting -main

换句话说,没有机会在控制台输入文本供(read-line)阅读。

我应该如何让 Clojure 等待输入字符和换行符并返回相应的字符串?

(我在 Linux Mint 11 上使用 GNOME Terminal 2.32.1,在 Java 1.6.0_26 Java HotSpot(TM) 64 位服务器 VM 上使用 Leiningen 1.6.1.1,Clojure 版本 1.2.1。)

更新:如果我运行lein repl,我可以(println (read-line)),但当我有-main 函数并使用lein run 运行时则不行。

【问题讨论】:

  • @amalloy 您链接到的答案中最好的猜测是这是 swank-clojure/SLIME 的问题。我没有使用其中任何一个。
  • 你有没有试过直接用 java -cp clojure.jar clojure.main /path/to/myscript.clj 运行脚本来放弃其他问题,专注于 lein run 问题?
  • @jneira 这似乎是 lein run 的问题。感谢您的建议。

标签: clojure console-application user-input leiningen


【解决方案1】:

我也遇到过类似的问题,于是构建了一个 jar 文件然后运行它。

lein uberjar
java -jar project-standalone.jar

它有点慢,虽然它让我解开了。一个适用于 repl 的答案将 变得更好

【讨论】:

  • 你是对的;这很慢,但它有效。看来 lein run 有问题。
  • 有同样问题的人应该注意,在以这种方式运行独立 jar 之前,他们需要在其命名空间声明中添加 (:gen-class)。
【解决方案2】:

不确定问题的 lein 方面,但在 emacs 中绝对不可能使 stdin 工作。但是,如果您想从用户那里获取文本,您可以使用 JOptionPane 轻松完成,就像我的小井字游戏中的以下代码一样:

(defn get-input []
  (let [input (JOptionPane/showInputDialog "Enter your next move (row/column)")]
    (map #(Integer/valueOf %) (.split input "/"))))

【讨论】:

    【解决方案3】:

    试试“lein trampoline run”。请参阅http://groups.google.com/group/leiningen/browse_thread/thread/a07a7f10edb77c9b 了解更多详情,请参阅https://github.com/technomancy/leiningen

    问:我无法访问项目中的标准输入。

    答:Leiningen 用来生成阻止访问控制台输入的新进程的库中存在问题。这意味着像 read-line 这样的函数在大多数情况下都不会像预期的那样工作,尽管 repl 任务必须包含一个解决方法。您还可以使用 trampoline 任务在 Leiningen 退出后启动项目的 JVM,而不是将其作为子进程启动。

    【讨论】:

      【解决方案4】:

      用现在在 ns swank.core 中的宏 with-read-line-support 包装您的 read-line 调用 [我相信因为 swank-clojure 1.4+]:

      (use 'swank.core)
      (with-read-line-support 
        (println "a line from Emacs:" (read-line)))
      

      感谢 Tavis Judd 的修复。

      【讨论】:

        【解决方案5】:

        您可以使用read 并使用字符串作为输入。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-11-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-21
          • 1970-01-01
          相关资源
          最近更新 更多