2012-05-14 8 views
5

Estoy tratando de llamar al clojure.walk/stringify-keys en un mapa que puede incluir instancias de registro. Como stringify-keys es recursivo, intenta convertir las claves en mi registro, (ya que (map? record-var) es verdadero) lo que causa un error. ¿Hay alguna manera de decir si una var es un registro en lugar de solo un mapa de Clojure? I me gusta proporcionar mi propia implementación de stringify-keys que sea compatible con registros.Distinguir una instancia de registro de un mapa

La implementación actual de stringify-keys, ocurre lo siguiente:

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

(defrecord Rec [x])  

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

Esto hace que la siguiente excepción: UnsupportedOperationException No se puede crear vacío: user.Rec user.Rec (NO_SOURCE_FILE: 1)

Respuesta

5

Records parecen implementar la interfaz marcador 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 

actualización 1.6 ahora tiene las funciones record?

1

que pueda compruebe el tipo de cada miembro y vea si realmente es un mapa u otra cosa (donde se presume que algo más es un registro)

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