2

したがって、私の core.clj ファイルには次のものがあります。

(def page-buffer (BufferedReader. (InputStreamReader. (clojure.java.io/input-stream               (clojure.java.io/resource "mitochondria.html")))))    
(def parsed-page (atom ""))

そして後で:

(defn -main [& args]
(let [port (Integer/parseInt (first args))]
(swap! parsed-page  (with-open []
                      (.toString (reduce #(.append %1 %2)
                                         (StringBuffer.) (line-seq page-buffer)))))
(println "Server is starting")
(println "port: " port)
(run-server port)))

これをコンパイルしてから、uberjar に変換します。しかし、実行すると、swap! という行が表示されます。爆発します:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
at clojure.core$swap_BANG_.invoke(core.clj:2106)
at serve_pages_from_memory.core$_main.doInvoke(core.clj:29)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at serve_pages_from_memory.core.main(Unknown Source)

アトムを使用せずにこれを試してみたところ、すべて正常に機能しました (「def」で定義された var を文字列として使用) が、最終的にはこの var を複数のスレッドに送信したいので、これをアトムまたはエージェントにする必要があります。

私は何を間違えましたか?

アップデート:

ジェレミー・ハイラー、ありがとう。修正されましたが、結果は罪のように醜いです:

(defn parse-buffer [& everything-else]
(with-open []
(.toString (reduce #(.append %1 %2)
                   (StringBuffer.) (line-seq page-buffer)))))

(defn -main [& args]
(let [port (Integer/parseInt (first args))]
(swap! parsed-page parse-buffer)
(println "Server is starting")
(println "port: " port)
(run-server port)))

parse-buffer に引数を渡さなければ、エラーが発生します。しかし、私は引数を使用しないので、これは醜いです。私はこれを間違って書いているに違いないですよね?

4

1 に答える 1

3

に関数を渡す必要がありますswap!。現在、値を渡しています。

(let [foo (atom 1)]
  (swap! foo + 2)
  @foo)

上記の式は 3 を返します。渡された関数はアトムの現在の値を取得し、戻り値はアトムの新しい値になります。追加の引数は、指定された関数に渡されます。


更新についてコメントするには: はい、 で使用される関数に引数を与える必要がありますswap!。最初の引数は、アトムの現在の値です。ただし、機能させるためにハッキングする必要はありませんparse-buffer。無名関数でラップするだけです。

また、parse-buffer大幅に簡素化できます。line-seq指定されたリーダーから一連の行を返し、内部的にstr使用するためStringBuilder、シーケンスに適用するだけです。

(defn parse-buffer []
  (with-open [buf page-buffer]
    (apply str (line-seq buf))))

(defn -main [& args]
  (let [port (Integer/parseInt (first args))]
    (swap! parsed-page (fn [cur-val] (parse-buffer)))
    (println "Server is starting")
    (println "port: " port)
    (run-server port)))
于 2012-08-30T22:17:19.943 に答える