Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: How do I turn clojure code into a string that is evaluatable? It mostly works but lists are translated to raw parens, which fails

I have a simple structure like this:

(def example {:bbb "bbb" :xxx [1 2 3] :yyy '(3 5 7)})

If I write this out to a file it contains

{:bbb "bbb" :xxx [1 2 3] :yyy (3 5 7)}

Which is mostly correct, but if I load-file on this, it fails because it tries to treat 3 as a function (the parens are no longer quoted, so tries to evaluate as a function).

What is the right way to do this? Thanks!

like image 480
prismofeverything Avatar asked Feb 11 '12 02:02

prismofeverything


1 Answers

If you want to read back a Clojure datum previously written to a file as a literal, you need to use read or read-string rather than load-file:

(with-open [fd (java.io.PushbackReader.
                (io/reader (io/file "/path/to/file")))]
  (read fd))

You can call read multiple times to read successive forms (as long as you hold the Reader open, of course).

This involves no evaluation except when the #= reader macro occurs in the input stream, in which case the form immediately following it is evaluated at read time and replaced with the result in read's output (e.g. (read-string "#=(+ 1 2)") returns 3). To prohibit evaluation of #= prefixed forms bind *read-eval* to false.

like image 61
Michał Marczyk Avatar answered Oct 14 '22 02:10

Michał Marczyk