Reputation: 141
I have a file containing a map containing maps. I simply used spit to save the map to a file.The data looks like this(its a bit long):
{:10 #nelson_clojure.brain.skeleton{:state #object[clojure.lang.Atom 0x3df978b9 {:status :ready, :val 1}], :dendrites
#object[clojure.lang.Atom 0x7906578e {:status :ready, :val {:26 #object[clojure.lang.Atom 0x1542af63 {:status :ready, :val 0.4285714285714286}], :27 #object[clojure.lang.Atom 0xecfbe91 {:status :ready, :val 0.4285714285714286}]}}], :coordinate
#nelson_clojure.brain.coord{:x #object[clojure.lang.Atom 0x8a62297 {:status :ready, :val 27.428199846008223}], :y
#object[clojure.lang.Atom 0x61a91912 {:status :ready, :val 43.504147970413726}], :z #object[clojure.lang.Atom 0x1763992e {:status :ready, :val 61.042795873379504}]}}}
So I have a map with key- :10, skeleton is a record i created in a file called brain. The record skeleton contains the state of the neuron and some other info all of which are atoms. I want to load this back in the code.
I tried loading this using :
(defn load-neurons []
"load neurons from file"
(set! *default-data-reader-fn* tagged-literal)
(let [x (read-string (nth (get-neurons) 0))] (println (:state ((nth (keys x) 0) x ))))
(log/log "Neurons loaded.")
)
But when I deref the atom I get error [1] because
Also when I try to use print-dup:
(defn save-neurons [cluster]
(println "neuron" (first cluster))
(binding [*print-dup* true] (spit "test.neuron" (first cluster)))
)
I get error [2].
The code i used for simply writing the data structure to a file. The cluster is a collection of maps, one of which I showed above.
(defn save-neurons [cluster]
"save the neurons to their files"
(when-not (= cluster {}) (spit (str "neuron-data/" (name (ffirst cluster)) ".neuron" ) (apply array-map (first cluster)))
(save-neurons (into {} (rest cluster)))))
Error[1]: Exception in thread "main" java.lang.ClassCastException: class clojure.lang.TaggedLiteral cannot be cast to class java.util.concurrent.Future (clojure.lang.TaggedLiteral is in unnamed module of loader 'app'; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
Error [2]: Exception in thread "main" java.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class clojure.lang.Atom
Expected: no ERROR !!! I just want the data structure to be loaded.
I pray to the brave clojurists for a solution and to forgive my sins if I have made any.
Upvotes: 0
Views: 314
Reputation: 141
Never mind I solved it..just creates separate handler functions for different tags and solved it..heres all you need is :
(defn handle-coord[x] x)
(defn handle-object [x]
(def tags {'object handle-object,'nelson_clojure.brain.coord handle-coord })
(atom (:val (get (edn/read-string {:readers tags} (str x)) 2))))
(defn skeleton [x] x)
and a reader functions
(defn load-neurons []
"load neurons from file"
(def tags {'nelson_clojure.brain.skeleton utility/skeleton, 'nelson_clojure.brain.coord utility/handle-coord, 'object utility/handle-object})
(let [x (map #(edn/read-string {:readers tags} %)(get-neurons))] (swap! brain/neural-cluster (fn [_] (apply merge x))))
(log/log "Neurons loaded.")
)
pretty easy...eh...tagged literals rock.
Upvotes: 0