3

私はClojureを初めて使用し、を再バインドして出力をファイルにリダイレクトしようとしています*out*。単純なケースでは、それはうまく機能します:

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

これは私が期待することを行い、ファイルtest.txtに「Hi」を出力します。ただし、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
4

1 に答える 1

5

あなたは怠惰なバグに噛まれました。

バインディングの前後にdoallまたはを配置しますdorun

(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
于 2013-02-15T21:03:16.083 に答える