2010-12-22 45 views
5

我試圖用* print-dup *來允許將clojure數據寫入文件 然後再讀回來,但是,即使在這種簡單情況下,我也遇到了問題。有什麼我做錯了嗎?我需要做什麼 才能使其發揮作用?如何使用 * print-dup *在clojure中打印記錄?一個簡單的例子

Clojure 1.3.0-alpha3-SNAPSHOT 
user=> (defrecord TreeNode [val left right]) ;;create the record 
user.TreeNode 
user=> (TreeNode. 5 nil nil) 
#:user.TreeNode{:val 5, :left nil, :right nil} ;; it works just fine 
user=> (binding [*print-dup* true] (prn (TreeNode. 5 nil nil))) ;; use *print-dup* to support reading in and preserving type 
#=(user.TreeNode/create {:val #=(java.lang.Long. "5"), :left nil, :right nil}) ;; this is the form we need to copy paste 
nil 
user=> #=(user.TreeNode/create {:val #=(java.lang.Long. "5"), :left nil, :right nil}) ;;trying to copy and paste 
IllegalArgumentException No matching method found: create 
clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:50) ;;we have an error 
user=> 

回答

3

作爲alpha8的更新,在簡單情況下,帶有記錄的* print-dup *現在可用。

user=> (defrecord TreeNode [val left right]) 
user.TreeNode 
user=> (TreeNode. 5 nil nil) 
#user.TreeNode{:val 5, :left nil, :right nil} 
user=> (binding [*print-dup* true] (prn (TreeNode. 5 nil nil))) 
#user.TreeNode[5, nil, nil] 
nil 
user=> #user.TreeNode[5, nil, nil] 
#user.TreeNode{:val 5, :left nil, :right nil} 
user=> 
6

記錄不以可評估形式打印。我們添加了自己的defrecord2,其中包括支持創建構造函數和使用構造函數打印它們的print/pprint支持(可以將它們評估回原始記錄)。這是更docely更多hereherecode在這裏。

在2010年10月的Clojure Conj會議上,我問Rich Hickey有關這個問題,他說構造函數和讀者對記錄的支持是爲將來計劃的。

+0

在此處發生的未來版本中的記錄設計工作:http://dev.clojure.org/display/design/defrecord+improvements – 2011-01-23 14:15:02

2

變通的方法在1.2:

(defn- extend-print-dup [record-class] 
    (defmethod print-dup record-class [o w] 
    (.write w "#=(") 
    (.write w (.getName ^Class (class o))) 
    (.write w ". ") 
    (dorun (map (fn [a] (print-dup a w) (.write w " ")) (vals o))) 
    (.write w ")"))) 

(defrecord Hl7Field [protospec segname fname pos hl7type values]) 
(extend-print-dup Hl7Field) 

=> (def a (Hl7Field. "p" "PV1" "toto" 0 "ST" ["c" "d"])) 
=> (binding [*print-dup* true] (prn a)) 
#=(higiebus.bus.protocol.hl7.Hl7Field. "p" "PV1" "toto" 0 "ST" ["c" "d"]) 

=> #=(higiebus.bus.protocol.hl7.Hl7Field. "p" "PV1" "toto" 0 "ST" ["c" "d"]) 
{:protospec "p", :segname "PV1", :fname "toto", :pos 0, :hl7type "ST", :values ["c" "d"]} 

你可以換通話,延長打印,DUP在自定義defrecord宏。