On Tuesday, 10 May 2016 10:11:58 UTC+1, Simon Brooke wrote:
>
> On Monday, 9 May 2016 16:55:59 UTC+1, Alex Miller wrote:
>>
>> Clojure is designed with enough extensibility to modify the printer and 
>> reader to cover this case.
>>
>> You can define a custom print strategy for these types by extending the 
>> print-dup multimethod. If you print it as a tagged literal, you can also 
>> define a custom reader that can read it back as the appropriate type. Or 
>> you can just happen to write it as a form that constructs a Java object if 
>> that's possible. (I don't know the Joda classes well.)
>>
>> Print methods typically look like this:
>>
>> (defmethod print-dup org.joda.time.DateTime
>>   [date-time ^java.io.Writer w]
>>   (.write w (format "#org.joda.time.DateTime[%d]")))
>>
>> That particular format should produce a string like 
>> #org.joda.time.DateTime[1462809085214] which when read will call the 
>> DateTime constructor with the long value. 
>>
>> Or you could write your own custom tagged literal format and define and 
>> install a reader for that tag that refers to a function that does whatever 
>> you need.
>>
>> And I would recommend never using Java serialization in either Clojure or 
>> Java. :) 
>>
>
> Fair enough, thanks. I looked for printer macros in the documentation but 
> didn't find them; I didn't think of multimethods. 
>
> Thanks again.
>

Right. I investigated the nippy library but it too needs work to read and 
write joda time objects, and I didn't have anything to go on (and I'm under 
time pressure) so I left it.

Following Alex Miller's advice above and making use of an excellent blog at 
http://proofbyexample.com/print-and-read-in-clojure.html I solved the 
problem as follows:

(ns opsdata.persistence
  "Serialising/deserialsing mixed Clojure/JodaTime data.")

;; I made use of the advice at 
http://proofbyexample.com/print-and-read-in-clojure.html
;; in writing this file.

;; Make it possible to print joda DateTime instances in re-readable form, 
for persistence.
(defmethod print-dup org.joda.time.DateTime
  [dt out]
  (.write out (str "#=" `(org.joda.time.DateTime. ~(.getMillis dt) 
~org.joda.time.DateTimeZone/UTC))))


;; Make it possible to print joda Interval instances in re-readable form, 
for persistence.
(defmethod print-dup org.joda.time.Interval
  [value out]
  (.write out (str "#=" `(org.joda.time.Interval. ~(.getStartMillis value) 
~(.getEndMillis value) ~org.joda.time.DateTimeZone/UTC))))


;; Make it possible to print joda DateTimeZone instances in re-readable 
form, for persistence.
(defmethod print-dup org.joda.time.DateTimeZone
  [value out]
  (.write out (str "#=" `(org.joda.time.DateTimeZone/forID ~(.getID 
value)))))


(defn persist-to-file
  "Persist this `value` in the file at this `file-path`."
  [value file-path]
  (binding
    [*print-dup* true]
    (spit file-path (with-out-str (pr value)))))


(defn recover-from-file
  "Read a persisted value from this `file-path`."
  [file-path]
  (binding
    [*read-eval* true]
    (read-string (slurp file-path))))

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to