Hi all, I've just read Alan Malloy's excellent clojure persistence article at
http://amalloy.hubpages.com/hub/Dont-use-XML-JSON-for-Clojure-only-persistence-messaging Then I wanted to add a feature for persisting and reloading clojure data that also contains vertices and edges of some java graph datastructure. In contrast to his java.util.Date example, those cannot be simply created but have to be retrieved in the context of the graph that holds the vertex or edge in question. All vertices and all edges have a numeric and unique id in their graph, and a graph itself has a unique graph id (some string). A vertex can be retrieved by id using (vertex mygraph id), and it's likewise for edges (edge mygraph id). So my plan was to serialize vertices and edges as calls to those functions where the graph is looked up in a hash-map that has to be bound dynamically when reading the data back. That's what I came up with: --8<---------------cut here---------------start------------->8--- (def ^:dynamic *serialization-bindings* nil) (defmethod print-dup Vertex [v out] (.write out (str "#=" `(vertex (*serialization-bindings* ~(id (graph v))) ~(id v))))) (defmethod print-dup Edge [e out] (.write out (str "#=" `(edge (*serialization-bindings* ~(id (graph e))) ~(id e))))) (defn tg-pr [x] (binding [*print-dup* true] (pr-str x))) --8<---------------cut here---------------end--------------->8--- Testing that (rg is a memoized fn that returns just some sample graph), I get ==> (tg-pr [1 2 3 (vertex (rg) 1) 4]) "[1 2 3 #=(de.uni-koblenz.funtg.core/vertex (de.uni-koblenz.funtg.core/*serialization-bindings* \"c06de1c7-f4ec0906-21cfbc86-28c31aa1\") 1) 4]" Looks good, I'd say. So my reloading function only needs to bind *serialization-bindings* to a map from graph id to graph, and it should work. --8<---------------cut here---------------start------------->8--- (defn tg-read [str & gs] (binding [*serialization-bindings* (into {} (map (fn [g] [(id g) g]) gs)) *print-dup* true] (binding [*print-dup* false] ;; For debugging... (println *serialization-bindings*)) (read-string str))) --8<---------------cut here---------------end--------------->8--- However, using that, I get an exception. de.uni-koblenz.funtg.test.core> (tg-read (tg-pr [1 2 3 (vertex (rg) 1) 4]) (rg)) {c06de1c7-f4ec0906-21cfbc86-28c31aa1 #<RouteMapImpl de.uni_koblenz.jgralabtest.schemas.greqltestschema.impl.std.RouteMapImpl@5203e0c6>} ; Evaluation aborted. No implementation of method: :vertex of protocol: #'de.uni-koblenz.funtg.core/IDOps found for class: clojure.lang.PersistentList [Thrown class java.lang.IllegalArgumentException] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:495) 1: de.uni_koblenz.funtg.core$eval6716$fn__6717$G__6705__6724.invoke(core.clj:381) 2: clojure.lang.Var.invoke(Var.java:405) 3: clojure.lang.AFn.applyToHelper(AFn.java:163) 4: clojure.lang.Var.applyTo(Var.java:518) 5: clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1041) 6: clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:618) 7: clojure.lang.LispReader.readDelimitedList(LispReader.java:1126) 8: clojure.lang.LispReader$VectorReader.invoke(LispReader.java:1061) 9: clojure.lang.LispReader.read(LispReader.java:180) 10: clojure.lang.RT.readString(RT.java:1681) 11: clojure.core$read_string.invoke(core.clj:3359) 12: de.uni_koblenz.funtg.core$tg_read.doInvoke(core.clj:1041) The printed *serialization-bindings* map looks correct. But the exception message indicates that the `vertex' function was called with a list as first parameter. That would mean that in *serialization-bindings* the graph id was mapped to some list?!? What's wrong here? (Clojure 1.3 if that matters...) Thanks for any pointers, Tassilo -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en