Or (load-string "(+ 1 (+ 2 4))") Jonathan
On Fri, Sep 9, 2011 at 5:14 PM, Chouser <chou...@gmail.com> wrote: > On Thu, Sep 8, 2011 at 5:16 PM, Tassilo Horn <tass...@member.fsf.org> > wrote: > > 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 > > I haven't tried all the above, but I had a couple thoughts that might help: > > First, inside #=(), arguments aren't evaluated. They act as if quoted: > > #=(+ 1 (+ 2 4)) > ; ClassCastException clojure.lang.PersistentList cannot be cast to > java.lang.Number clojure.lang.Numbers.add (Numbers.java:126) > > The list (+ 2 4) is passed as a list to the outer +, which fails > because it's expecting a number not a list. So one alternative would > be: > > #=(+ 1 #=(+ 2 4)) > ;=> 7 > > But please consider another alternative: > > (+ 1 (+ 2 4)) > ;=> 7 > > That is, if you're going to be evaluating a large amount of code while > reading your data back into memory, why not just go ahead and eval it > instead of just reading it? > > (read-string "#=(+ 1 #=(+ 2 4))") > vs. > (eval (read-string "(+ 1 (+ 2 4))")) > > --Chouser > > -- > 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 > -- 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