Clojure输出绑定在for循环中重置

时间:2013-02-15 20:21:42

标签: clojure leiningen

我是Clojure的新手,我正在尝试通过重新绑定*out*将输出重定向到文件。在一个简单的例子中,它运作良好:

(binding [*out* (new java.io.FileWriter "test.txt")]
  (println "Hi"))

这就是我所期望的,将“Hi”打印到文件test.txt。但是,如果我引入for循环,那么事情就会出错:

(binding [*out* (new java.io.FileWriter "test.txt")]
  (for [x [1 2]]
    (println "Hi" x)))

这次,所有输出都转到stdout,文件为空。这是怎么回事?

我正在使用Leiningen,如果这有任何区别:

Leiningen 2.0.0 on Java 1.7.0_13 Java HotSpot(TM) 64-Bit Server VM

1 个答案:

答案 0 :(得分:5)

你被这个懒惰的小虫咬了。

在for和绑定

中放置doalldorun
(binding [*out* (new java.io.FileWriter "test.txt")]
  (doall (for [x [1 2]]
           (println "Hi" x))))

在您的示例中,正在进行打印,然后在从绑定返回后,repl 将打印结果。因此,在打印时,绑定不再存在。

没有打印任何内容,因为结果是一个懒惰的序列,稍后将在使用时进行评估

user> (def result (binding [*out* (new java.io.FileWriter "test.txt")]
        (for [x [1 2]] 
          (println "Hi" x))))
#'user/result

当repl打印结果时,将评估printlns:

user> result
(Hi 1
Hi 2 
nil nil) 

如果我们强制评估绑定中for返回的延迟序列 没有任何内容打印到repl,

user> (def result (binding [*out* (new java.io.FileWriter "test.txt")]
  (doall (for [x [1 2]]             
          (println "Hi" x))))) 
#'user/result 
user> result
(nil nil) 

而输出最终在文件中:

arthur@a:~/hello$ cat test.txt 
Hi 1
Hi 2