is there a way to read all the forms in a clojure file?

☆樱花仙子☆ 提交于 2019-12-21 12:25:28

问题


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.


回答1:


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

```




回答2:


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)))))


来源:https://stackoverflow.com/questions/24922478/is-there-a-way-to-read-all-the-forms-in-a-clojure-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!