请注意,这不仅对clojure.java(shell)和clojure.java.browse很重要,而且还将使在x)dopen上使用的平台上的ClojureScript浏览器REPL能够正确启动浏览器。目前,ClojureScript快速入门说明在许多系统上实际上是出错的。大多数ClojureScript的新用户不会喜欢调试这样的东西(或者也许我只是比大多数人更固执:)))。
在某些平台上,clojure.java.browse/browse-url通过xdg-open调用clojure.java.shell/sh来执行cmd命令。作为正确的*Nix实用程序,xdg-open将它的打开文件描述符传递到新进程中。(我不知道x)dopen是否在某处有文档记录,但这很容易演示。)
clojure.java.shell/sh总是从执行的过程读取STDOUT和STDERR流。当目的是收集子进程的输出时,当然是件好事。然而,当用xdg-open启动浏览器时,这些流只有在浏览器退出时才会关闭。对于clojure.java.browse/browse-url的调用者来说,看起来这个函数似乎“永远不会”返回。
我们需要clojure.java.shell/sh的一个变体(或者sh的一个选项)忽略输出流并仅返回退出代码。我们仅仅使用子进程的副作用。与使用doseq代替map有些类似,但我们确实想要子进程的退出代码。
为了让ClojureScript浏览器REPL工作,我复制了clojure.java.{browse,shell}的本地副本,向clojure.java.shell添加了一个(启动)函数,该函数忽略I/O流但返回退出代码,并将browse-url修改为使用启动。好多了!浏览器和REPL都与快速入门说明中承诺的一样。
个人笔记:尽管我刚刚开始实验ClojureScript,但我已经使用Clojure几年的时间了。
由: Alex Miller