2012-09-13 41 views
2

我有一段代碼來實現地圖原子的裁判包含地圖如何使根類對象顯示更好

> (def a (example.DynaRec.) 

> (dosync (assoc! a 3 {:id 3 :contents "stuff"} 4 {:id 4})) 
;;=> #[[email protected]: {4 [<[email protected]: {:id 4}] 3 [[email protected]: {:id 3 :contents "stuff"}]] 

我想要改變這個顯示的方式repl以便它只輸出

> a 
;;=> ({:id 3 :contents "stuff"} 
;; {:id 4}) 

這怎麼辦?代碼如下所示:

 
(ns example.dyna-rec 
    (:gen-class 
    :name example.DynaRec 
    :prefix "-" 
    :init init 
    :state state 
    :extends clojure.lang.AFn 
    :implements [clojure.lang.IDeref 
       clojure.lang.Seqable 
       clojure.lang.ILookup 
       clojure.lang.ITransientMap])) 

(defn- $ [this] (:data (.state this))) 

(defn- valid? 
    ([e] 
    (valid? e [])) 
    ([this e] 
    (every? #(contains? e %) (:required (.state this))))) 

(defn -deref [this] @($ this)) 

(defn -valAt 
    ([this k] ((-deref this) k nil)) 
    ([this k nv] 
    (if-let [vatom ((-deref this) k nv)] 
     @vatom))) 

(defn -invoke 
    ([this k] (-valAt this k)) 
    ([this k nv] -valAt this k nv)) 

(defn -seq [this] (seq (-deref this))) 

(defn -count [this] (count (-deref this))) 

(defn -without [this obj] 
    (alter ($ this) dissoc obj)) 

(defn -assoc 
    ([this obj] (-assoc this (:id obj) obj)) 
    ([this k v] 
    {:pre [(valid? this v) 
      (= k (:id v))]} 
    (alter ($ this) assoc k (atom v)) 
    this)) 

(defn -conj [this obj] 
    (-assoc this obj)) 

(defn -persistent [this] 
    (-deref this)) 

(defn -init [] 
    [[] {:required #{:id} 
     :data  (ref {})}]) 

回答

5

爲了延續經典Java模型(這Clojure的擁抱),你可以實現自己的.toString產生正確的字符串,然後告訴REPL如何正確打印此新類

開始加入了超級基本toString到DYNA-rec.clj:

(defn- -toString [this] 
    (str (into {} this))) 

這可以這樣調用:

(defn- -toString [this] 
(str (zipmap (keys this) (map deref (vals this))))) 

example.DynaRec> (.toString a) 
"{}" 
example.DynaRec> (str a) 
"{}" 

進而提高打印機以匹配所需的輸出:

(defn- -toString [this] 
    (str (zipmap (keys this) (map deref (vals this))))) 

並對其進行測試:

example.DynaRec> (str a) 
"{3 {:id 3, :contents \"stuff\"}, 4 {:id 4}}" 
example.DynaRec> 

這仍然沒有在REPL正確打印,所以我們需要延長多法由打印機(打印方法)使用,由REPL用於瞭解您的新類別:

(defmethod print-method 
    example.DynaRec 
    [this, w] 
    (print-method (zipmap (keys this) (map deref (vals this))) w)) 

這產生你想要的:

example.DynaRec> a 
{3 {:id 3, :contents "stuff"}, 4 {:id 4}}