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

Reply via email to