2012-05-14 71 views
5

我試圖在可能包含記錄實例的地圖上調用clojure.walk/stringify-keys。由於stringify鍵是遞歸的,它會嘗試轉換我的記錄上的鍵(因爲(map? record-var)爲true)會導致錯誤。有沒有什麼辦法可以告訴var是否是記錄而不是Clojure地圖? I d喜歡提供我自己的實現stringify-keys這是記錄感知。區分記錄實例和地圖

目前執行的stringify-keys造成以下結果:

(use '[clojure.walk :only [stringify-keys]]) 

(defrecord Rec [x])  

(let [record (Rec. "foo") 
     params {:x "x" :rec record}] 
    (stringify-keys params)) 

這將導致以下異常:UnsupportedOperationException異常無法創建空:user.Rec user.Rec(NO_SOURCE_FILE:1)

回答

5

條記錄似乎實現IRecord標記接口:

user=> (defrecord Rec [x])  
user.Rec 

user=> (require '[clojure.reflect :as r]) 
nil 
user=> (:bases (r/reflect Rec)) 
#{java.io.Serializable clojure.lang.IKeywordLookup clojure.lang.IPersistentMap clojure.lang.IRecord java.lang.Object clojure.lang.IObj clojure.lang.ILookup java.util.Map} 

user=> (instance? clojure.lang.IRecord (Rec. "hi")) 
true 

更新 1.6現在有record?功能

1

可以檢查每個成員的類型,看看它是否真的是地圖或別的東西(其他東西被認爲是記錄)

user> (type {:a 1 :b 2}) 
clojure.lang.PersistentArrayMap