我一直在玩clojure,并一直用它来构建一个简单的小型音频播放器。奇怪的是,有时,也许有二十分之一,当联系服务器时,我会收到以下错误:
2010-04-20 15:33:20.963::WARN: Error for /control
java.lang.StackOverflowError
at clojure.lang.RT.seq(RT.java:440)
at clojure.core$seq__4245.invoke(core.clj:105)
at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:440)
at clojure.core$seq__4245.invoke(core.clj:105)
at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:440)
at clojure.core$seq__4245.invoke(core.clj:105)
at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:440)
at clojure.core$seq__4245.invoke(core.clj:105)
at clojure.core$filter__5084$fn__5086.invoke(core.clj:1794)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:56)
at clojure.lang.RT.seq(RT.java:440)
...
如果我再次这样做,它总是有效的。所以它似乎与时间或某事有关。有问题的代码是:
(defn add-track [t]
(common/ref-add tracks t))
(defn add-collection [coll]
(doseq [track coll] (add-track track)))
和
(defn ref-add [ref value]
(dosync (ref-set ref (conj @ref value))))
从此函数中提取coll:
(defn tracks-by-album [album]
(sort sort-tracks (filter #(= (:album %) album) @tracks)))
使用:
(defn get-album-from-track [track]
(seq/find-first #(= (:album track) (:name %)) @albums))
(defn sort-tracks [track1 track2]
(cond (= (:album track1) (:album track2))
(cond (and (:album-track track1) (:album-track track2))
(< (:album-track track1) (:album-track track2))
:else 0)
:else
(> (:year (get-album-from-track track1)) (:year (get-album-from-track track2)))))
它或多或少直接来自我收到的请求:
(when-handle-command cmd params (audio/tracks-by-album decoded-name))
(defn when-handle-command [cmd params data]
(println (str "handling command:" cmd))
....)
我从来没有在我的日志中获得处理命令,所以当它按照逐个专辑进行操作时必须死掉。
因此它看起来似乎是堆栈跟踪中的逐个轨道功能。我只是不明白为什么它有时会起作用,有时却不起作用。我说它是逐个专辑的,因为它是唯一可以过滤的功能(包括它的孩子),如跟踪中所示。
所有源代码均可在http://code.google.com/p/mucomp/获得。这是我的小爱好项目,学习clojure,到目前为止,这是一个非常错误(这只是一个错误:))所以我真的不想告诉太多人呢:)
答案 0 :(得分:1)
我在clojure邮件列表上问了一个问题。似乎答案是过滤器返回一个懒惰的seq,当你链接它们时,你会在某个时刻以堆栈溢出结束。可以使用doall强制生成序列。