tags:

views:

187

answers:

2

I want to persist my data to a file and restore the data when I rerun the program.

I've defined my defstruct as such:

(defstruct bookmark :url :title :comments)

Program will simply do the following:
1. Load the defstruct's from url-db.txt
2. Read from an import file(s) passed into *command-line-args* and add to internal data var.
3. Rewrite the url-db.txt file.

Sample import file:

www.cnn.com|News|This is CNN
www.msnbc.com|Search|
news.ycombinator.com|News|Tech News

+2  A: 

Use spit and slurp (example taken from http://www.nofluffjuststuff.com/blog/stuart_halloway/2008/09/pcl__clojure_chapter_3_1). Generally this technique is called serializing.

(defn save-db [db filename]
  (spit 
   filename 
   (with-out-str (pr db))))

(defn load-db [filename] 
  (with-in-str (slurp filename)
    (read)))

(The earlier print error was there in the original code, and I was dumb and didn't check it. Thanks)

Tom Crayford
(def x (struct bookmark "news.ycombinator.com" "News" "Tech News")); Doesn't handle "Things in quotes"
His example had a name in quotes. When I tried to reload the data it didn't work (save-db x "url-db.txt") ... (def y (load-db "url-db.txt"))
+6  A: 

Tom Crayford's answer is close, but use the "pr" function instead of "print". "pr" produces strings that can be read back in with "read".

(defn save-db [db filename]
  (spit 
   filename 
   (with-out-str (pr db))))

(defn load-db [filename] 
  (with-in-str (slurp filename)
    (read)))

Note that this will not work if *print-dup* is set to true. See ticket #176 Note also that when you read the database back in, the records will be ordinary maps, not struct maps. Struct maps cannot yet be serialized with pr/read.

Stuart Sierra
Just for my own edification, is there a reason you used with-in-str and with-out-str instead of using read-string and pr-str?
alanlcode
Not really. Don't remember why I wrote it that way.
Stuart Sierra