13

Clojure 1.5 が導入されました。clojure.ednこれには、PushbackReader.

最初の 5 つのオブジェクトを読み取りたい場合は、次のようにします。

(with-open [infile (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))]
  (binding [*in* infile]
    (let [edn-seq (repeatedly clojure.edn/read)]
      (dorun (take 5 (map println edn-seq))))))

代わりにすべてのオブジェクトを印刷するにはどうすればよいですか? それらのいくつかが nil である可能性があることを考えると、EOF などをチェックする必要があるようです。から取得するものと同様の一連のオブジェクトが必要ですline-seq

4

2 に答える 2

16

使用:eof キー

http://clojure.github.com/clojure/clojure.edn-api.html

opts は、次のキーを含むことができるマップです: :eof - ファイルの終わりで返される値。指定されていない場合、eof は例外をスローします。

編集:申し訳ありませんが、それは十分な詳細ではありませんでした! ここに行きます:

(with-open [in (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))]
  (let [edn-seq (repeatedly (partial edn/read {:eof :theend} in))]
    (dorun (map println (take-while (partial not= :theend) edn-seq)))))

それはそれをするべきです

于 2013-03-06T00:50:07.533 に答える
3

これをもう一度見ました。これが私が思いついたものです:

(defn edn-seq
  "Returns the objects from stream as a lazy sequence."
  ([]
     (edn-seq *in*))
  ([stream]
     (edn-seq {} stream))
  ([opts stream]
     (lazy-seq (cons (clojure.edn/read opts stream) (edn-seq opts stream)))))

(defn swallow-eof
  "Ignore an EOF exception raised when consuming seq."
  [seq]
  (-> (try
        (cons (first seq) (swallow-eof (rest seq)))
        (catch java.lang.RuntimeException e
          (when-not (= (.getMessage e) "EOF while reading")
            (throw e))))
      lazy-seq))

(with-open [stream (java.io.PushbackReader. (clojure.java.io/reader "foo.txt"))]
  (dorun (map println (swallow-eof (edn-seq stream)))))

edn-seqはと同じ署名を持ち、既存の動作をすべて保持します。これは、人々がさまざまな方法でオプションをclojure.edn/read使用する可能性があることを考えると重要だと思います。:eofEOF例外を含む別の関数は、より良い選択のように思われましたが、それがとして表示されるため、どのようにキャプチャするのが最適かはわかりませんjava.lang.RuntimeException

于 2013-03-06T15:59:12.940 に答える