2014-07-23 9 views
6

Wenn ichgibt es eine Möglichkeit, alle Formulare in einer Clojure-Datei zu lesen?

(-> "<file>.clj" 
    (slurp) 
    (read-string)) 

verwenden, die nur die erste Form in der Datei gelesen werden (in der Regel der ns Erklärung). Gibt es eine Möglichkeit, eine Liste von Formularen aus der Datei abzurufen?

Ich würde bevorzugen, wenn keine externen Bibliotheken verwendet werden.

+2

Warum verwenden Sie 'load-file' nicht? – ntalbs

+0

@ntalbs Das wird alles bewerten. – Alex

Antwort

5

ein [ und ] auf den Anfang und das Ende der Schnur hält die ganze Datei in eine einzige Vektorform zu machen:

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 

`` `

+0

Sehr cool! Das habe ich total vergessen. – zcaudate

+1

Nicht so heiß, wenn die letzte Zeile ein Kommentar ist. – amalloy

+2

ohh guter Punkt! besser ein Newline nach dem [und vor dem] –

10

Diese Funktion öffnet einen Stream für Clojure liest aus und liest eifrig alle Formulare aus diesem Stream, bis read eine Ausnahme auslöst (dies passiert, wenn ein Parse-Fehler auftritt oder keine Formulare mehr zu lesen sind).

(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))))) 
Verwandte Themen