2010-05-18 6 views
11

Lorsque je veux lire une expression S stockée dans un fichier dans un programme Common Lisp en cours d'exécution, j'effectue les opérations suivantes:Clojure: équivalent à la fonction Common Lisp READ?

(defun load-file (filename) 
    "Loads data corresponding to a s-expression in file with name FILENAME." 
    (with-open-file (stream filename) 
    (read stream))) 

Si, par exemple, j'ai un fichier nommé foo.txt contenant le fichier S- expression (1 2 3), la fonction ci-dessus renverra cette expression S si elle est appelée comme suit: (load-file "foo.txt").

Je cherchais encore et encore et je n'ai pas trouvé de solution tout aussi élégante dans Clojure. Des idées?

Merci!

Répondre

8

Vous pouvez effectuer, par ex.

(require '[clojure.contrib.io :as io]) 

(io/with-in-reader (io/file "foo.txt") (read)) 
; => (1 2 3) 

Notez que vous aurez probablement envie de rebind *read-eval*-false premier. Notez également que ce qui précède fonctionne avec le contrib actuel HEAD (et fonctionnera presque certainement dans 1.2 quand il sera publié); pour Clojure 1.1, la même fonctionnalité est disponible dans les espaces de noms clojure.contrib.duck-streams et clojure.contrib.java-utils.

+0

Salut, quel est l'avantage, le cas échéant, de cette approche plus (lecture string (slurp "foo.txt")) – jkndrkn

+2

'slurp' /' io/slurp * 'slurp tout le contenu du fichier, même si' read-string' ne lira qu'un formulaire entier et rejettera le reste. L'approche 'with-in-reader' ne lira qu'un petit peu après le premier formulaire (en raison de la mise en mémoire tampon). En outre, vous pouvez avoir plus de formes dans le corps de 'with-in-reader'; en particulier, les invocations ultérieures de 'read' dans la même forme' with-in-reader' renverraient d'autres formes à partir du fichier. (Essayez d'utiliser '[(read) (read)]' comme le corps pour obtenir les deux formes initiales.) J'aurais posté votre réponse à côté de celui-ci si j'avais pensé à cela. :-) –

Questions connexes