2009-05-28 20 views
7

Tôi vừa mới bắt đầu chơi với Clojure và điều đầu tiên tôi nghĩ là cố gắng lưu trữ và lấy một danh sách các cấu trúc, như trong ví dụ của Suart Halloway here.Clojure: slurping structs từ file thất bại với các thuộc tính chuỗi có chứa khoảng trắng

My nhổ/Slurp của một hash của cấu trúc hoạt động tốt với, nếu tôi sử dụng trường hợp struct không gian trong chuỗi thuộc tính như sau:

(struct customer "Apple" "InfiniteLoop") 

Nhưng nếu tôi sử dụng này:

(struct customer "Apple" "Infinite Loop 1") 

tôi nhận được một lỗi:

Exception in thread "main" clojure.lang.LispReader$ReaderException: java.lang.ArrayIndexOutOfBoundsException: 7 (test-storing.clj:19) 
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2719) 
    at clojure.lang.Compiler$DefExpr.eval(Compiler.java:298) 
    at clojure.lang.Compiler.eval(Compiler.java:4537) 
    at clojure.lang.Compiler.load(Compiler.java:4857) 
    at clojure.lang.Compiler.loadFile(Compiler.java:4824) 
    at clojure.main$load_script__5833.invoke(main.clj:206) 
    at clojure.main$init_opt__5836.invoke(main.clj:211) 
    at clojure.main$initialize__5846.invoke(main.clj:239) 
    at clojure.main$null_opt__5868.invoke(main.clj:264) 
    at clojure.main$legacy_script__5883.invoke(main.clj:295) 
    at clojure.lang.Var.invoke(Var.java:346) 
    at clojure.main.legacy_script(main.java:34) 
    at clojure.lang.Script.main(Script.java:20) 
Caused by: clojure.lang.LispReader$ReaderException: java.lang.ArrayIndexOutOfBoundsException: 7 
    at clojure.lang.LispReader.read(LispReader.java:180) 
    at clojure.core$read__4168.invoke(core.clj:2083) 
    at clojure.core$read__4168.invoke(core.clj:2081) 
    at clojure.core$read__4168.invoke(core.clj:2079) 
    at clojure.core$read__4168.invoke(core.clj:2077) 
    at chap_03$load_db__54.invoke(chap_03.clj:71) 
    at clojure.lang.AFn.applyToHelper(AFn.java:173) 
    at clojure.lang.AFn.applyTo(AFn.java:164) 
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2714) 
    ... 12 more 
Caused by: java.lang.ArrayIndexOutOfBoundsException: 7 
    at clojure.lang.PersistentArrayMap$Seq.first(PersistentArrayMap.java:216) 
    at clojure.lang.APersistentMap.hashCode(APersistentMap.java:101) 
    at clojure.lang.Util.hash(Util.java:55) 
    at clojure.lang.PersistentHashMap.entryAt(PersistentHashMap.java:134) 
    at clojure.lang.PersistentHashMap.containsKey(PersistentHashMap.java:130) 
    at clojure.lang.APersistentSet.contains(APersistentSet.java:33) 
    at clojure.lang.PersistentHashSet.cons(PersistentHashSet.java:59) 
    at clojure.lang.PersistentHashSet.create(PersistentHashSet.java:34) 
    at clojure.lang.LispReader$SetReader.invoke(LispReader.java:974) 
    at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:540) 
    at clojure.lang.LispReader.read(LispReader.java:145) 
    ... 20 more 

Tùy thuộc vào số lượng các trường trong struct, tôi có thể cũng chỉ nhận được một phần của chuỗi như một tên thuộc tính thay vì lỗi. Ví dụ: Vòng 1

tôi sử dụng một cửa hàng chức năng như thế này:

(defn store-customer-db [customer-db filename] 
    (spit filename (with-out-str (print customer-db)))) 

Và một read-chức năng như thế này:

(defn load-db [filename] 
    (with-in-str (slurp filename)(read))) 

Từ các tập tin đầu ra của nước bọt tôi có thể thấy rằng bản in không đưa ra các dấu ngoặc kép cho các chuỗi mà dường như là một vấn đề cho slurp. Giải pháp chính xác cho điều này là gì?

Phiên bản Clojure của tôi là 1.0 và phần đóng góp là ảnh chụp nhanh vài tuần trước.

+0

Bạn có thể nhận được câu trả lời có thẩm quyền và ngay lập tức trong #clojure (irc). – alphazero

Trả lời

10

printprintln có nghĩa là cho đầu ra có thể đọc được. Nếu bạn muốn in một cái gì đó có nghĩa là để được đọc lại sau, hãy sử dụng pr hoặc prn.

user> (read-string (with-out-str (prn {"Apple" "Infinite Loop"}))) 
{"Apple" "Infinite Loop"} 

Trong đó:

user> (read-string (with-out-str (print {"Apple" "Infinite Loop"}))) 
java.lang.ArrayIndexOutOfBoundsException: 3 (NO_SOURCE_FILE:0) 

Đó là cố gắng để chạy mã này:

(read-string "{Apple Infinite Loop}") 

trong đó có một số lẻ các phím/giá trị. Lưu ý việc thiếu dấu ngoặc kép xung quanh các khóa/giá trị băm riêng lẻ. Ngay cả khi đọc này hoạt động (tức là nếu bạn tình cờ cung cấp một số lượng thông số), thì những gì nó đọc sẽ không phải là một bản đồ băm đầy Strings, mà là Biểu tượng. Vì vậy, bạn sẽ nhận được một cái gì đó khác với những gì bạn sản xuất.

user> (map class (keys (read-string (with-out-str (print {"foo bar" "baz quux"}))))) 
(clojure.lang.Symbol clojure.lang.Symbol) 
2

Đối, nói:

(def hashed-hobbits {:bilbo "Takes after his Mother's family" :frodo "ring bearer"}) 

Bạn chỉ cần:

(spit "hobbitses.txt" hashed-hobbits) 

và đọc nó trở lại:

(def there-and-back-again (read-string (slurp "hobbitses.txt"))) 

nhổ/Slurp kết thúc tốt đẹp tất cả trong một chuỗi nhưng sử dụng chuỗi đọc trên slurp diễn giải chuỗi lại thành cl mã/dữ liệu ojure. Hoạt động trên cấu trúc dữ liệu trollish quá!

+0

điều này thật tuyệt vời, cảm ơn – scape

Các vấn đề liên quan