2012-05-14 16 views
5

Próbuję wywołać clojure.walk/stringify-keys na mapie, która może zawierać wystąpienia rekordów. Ponieważ stringify-keys jest rekurencyjne, próbuje przekonwertować klucze w moim rekordzie (ponieważ (map? record-var) jest prawdziwe), co powoduje błąd. Czy istnieje sposób, aby stwierdzić, czy var jest rekordem, a nie tylko mapą Clojure? I Chciałbym zapewnić moją własną implementację stringify-keys, która jest zdalna.Rozróżnianie instancji rekordów z mapy

Obecna implementacja stringify-keys powoduje następujące:

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

(defrecord Rec [x])  

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

Powoduje następujący wyjątek: UnsupportedOperationException Nie można utworzyć pusty: user.Rec user.Rec (NO_SOURCE_FILE: 1)

Odpowiedz

5

Records wydaje się wdrożenie IRecord interfejs markera:

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 

Aktualizacja 1.6 ma teraz funkcje record?

1

można sprawdź typ każdego członka i sprawdź, czy to naprawdę mapa, czy coś innego (gdzie coś innego jest uważane za rekord)

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