Reputation: 14258
If I use
(-> "<file>.clj"
(slurp)
(read-string))
That will only read the first form in the file (typically the ns declaration). Is there a way to retrieve a list of forms from the file?
I'd prefer if no external libraries are used.
Upvotes: 8
Views: 1031
Reputation: 20194
This function opens a stream for Clojure to read from, and eagerly reads all forms from that stream until read throws an exception (this happens if there is a parse error, or there are no more forms to read).
(import '[java.io PushbackReader])
(require '[clojure.java.io :as io])
(defn read-all
[file]
(let [rdr (-> file io/file io/reader PushbackReader.)]
(loop [forms []]
(let [form (try (read rdr) (catch Exception e nil))]
(if form
(recur (conj forms form))
forms)))))
Upvotes: 14
Reputation: 91577
stick a [
and ]
onto the start and end of the string to make the whole file into a single vector form:
user> (clojure.pprint/pprint
(read-string (str "[" (slurp "/home/arthur/hello/project.clj") "]")))
[(defproject
hello
"0.1.0-SNAPSHOT"
:description
"FIXME: write description"
:url
"http://example.com/FIXME"
:license
{:name "Eclipse Public License",
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies
[[org.clojure/clojure "1.5.1"] [clj-time "0.6.0"]]
:source-paths
["dev"])]
nil
```
Upvotes: 6