#(use clojure.contrib.server-socket)
(import (java.io BufferedReader
InputStreamReader
PrintWriter
OutputStreamWriter))
(defn hoge [in out]
(let [reader (BufferedReader. (InputStreamReader. in))
writer (PrintWriter. (OutputStreamWriter. out))]
(doall
(for [line (line-seq reader)]
(do
(.println writer line)
(.flush writer))))))
(create-server 6666 hoge)
#まだ言ってるのかって感じですが、clojureハッカソンのときにはまってた問題を短いコードで再現させました。
#echoサーバを作ろうと思ってこういうコードを書くと、一個前の行が出力されるんですが、何が原因なんでしょうか?
#何が原因なんですか?
#分かった!line-seq の中の lazy-seq の位置が問題ですね。
user> (use 'clojure.contrib.repl-utils)
user> (source line-seq)
(defn line-seq
"Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement java.io.BufferedReader."
[#^java.io.BufferedReader rdr]
(let [line (. rdr (readLine))]
(when line
(lazy-seq (cons line (line-seq rdr))))))
lazy-seq は内側の計算は遅延してくれるけど、外側の (readLine) は遅延してくれない。
なので常に一個余計に readLine されちゃう。
(let [line (. rdr (readLine))] も lazy-seq に包んじゃえばOK.