Well there is a remove method in ClassValue, http://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html#remove(java.lang.Class)and it seems that the cache is implemented in a way that it does not hold class objects, thus it does not prevent class from GCing (the cached value is stored in class object itself).
On Thu, Jan 30, 2014 at 3:40 PM, Ambrose Bonnaire-Sergeant < abonnaireserge...@gmail.com> wrote: > Is there any way to invalidate this cache? > > Thanks, > Ambrose > > > On Thu, Jan 30, 2014 at 9:35 PM, pron <ron.press...@gmail.com> wrote: > >> The bean function is a very useful Java interop feature that provides a >> read-only view of a Java Bean as a Clojure map. >> As it stands, the function performs introspection on the bean's class >> whenever the function is called: >> >> >> (defn bean >> "Takes a Java object and returns a read-only implementation of the >> >> >> map abstraction based upon its JavaBean properties." >> {:added "1.0"} >> >> >> [^Object x] >> (let [c (. x (getClass)) >> >> >> pmap (reduce1 (fn [m ^java.beans.PropertyDescriptor pd] >> >> >> (let [name (. pd (getName)) >> >> >> method (. pd (getReadMethod))] >> >> >> (if (and method (zero? (alength (. method >> (getParameterTypes))))) >> >> >> (assoc m (keyword name) (fn [] >> (clojure.lang.Reflector/prepRet (.getPropertyType pd) (. method (invoke x >> nil))))) >> >> >> m))) >> {} >> (seq (.. java.beans.Introspector >> >> >> (getBeanInfo c) >> >> >> >> (getPropertyDescriptors)))) >> v (fn [k] ((pmap k))) >> >> >> snapshot (fn [] >> (reduce1 (fn [m e] >> >> >> (assoc m (key e) ((val e)))) >> >> >> {} (seq pmap)))] >> >> >> >> (proxy [clojure.lang.APersistentMap] >> [] >> >> >> (containsKey [k] (contains? pmap k)) >> >> >> (entryAt [k] (when (contains? pmap k) (new clojure.lang.MapEntry k (v >> k)))) >> >> >> (valAt ([k] (when (contains? pmap k) (v k))) >> >> >> ([k default] (if (contains? pmap k) (v k) default))) >> >> >> (cons [m] (conj (snapshot) m)) >> >> >> (count [] (count pmap)) >> >> >> (assoc [k v] (assoc (snapshot) k v)) >> >> >> (without [k] (dissoc (snapshot) k)) >> >> >> (seq [] ((fn thisfn [plseq] >> >> >> (lazy-seq >> (when-let [pseq (seq plseq)] >> >> >> (cons (new clojure.lang.MapEntry (first pseq) (v (first >> pseq))) >> >> >> (thisfn (rest pseq)))))) (keys pmap)))))) >> >> >> >> >> >> I propose to cache the pmap value for each class using JDK 7's >> ClassValue<http://docs.oracle.com/javase/7/docs/api/>. >> Here's a proposed implementation: >> >> >> (def ^:private ^java.lang.ClassValue bean-class-value >> >> >> (proxy [java.lang.ClassValue] >> [] >> (computeValue [c] >> >> >> (reduce (fn [m ^java.beans.PropertyDescriptor pd] >> >> >> (let [name (. pd (getName)) >> >> >> method (. pd (getReadMethod)) >> >> >> type (.getPropertyType pd)] >> (if (and method (zero? (alength (. method >> (getParameterTypes))))) >> >> >> (assoc m (keyword name) (fn [x] >> (clojure.lang.Reflector/prepRet type (. method (invoke x nil))))) >> >> >> m))) >> {} >> (seq (.. java.beans.Introspector >> >> >> (getBeanInfo c) >> (getPropertyDescriptors))))))) >> >> >> >> (defn bean >> "Takes a Java object and returns a read-only implementation of the >> >> >> map abstraction based upon its JavaBean properties." >> {:added "1.0"} >> >> >> [^Object x] >> (let [c (. x (getClass)) >> >> >> pmap (.get bean-class-value c) >> >> >> v (fn [k] ((pmap k) x)) >> >> >> snapshot (fn [] >> (reduce (fn [m e] >> >> >> (assoc m (key e) ((val e) x))) >> >> >> {} (seq pmap)))] >> (proxy [clojure.lang.APersistentMap] >> >> >> [] >> (containsKey [k] (contains? pmap k)) >> >> >> (entryAt [k] (when (contains? pmap k) (new clojure.lang.MapEntry k (v >> k)))) >> >> >> (valAt ([k] (when (contains? pmap k) (v k))) >> >> >> ([k default] (if (contains? pmap k) (v k) default))) >> >> >> (cons [m] (conj (snapshot) m)) >> >> >> (count [] (count pmap)) >> (assoc [k v] (assoc (snapshot) k v)) >> >> >> (without [k] (dissoc (snapshot) k)) >> >> >> (seq [] ((fn thisfn [plseq] >> >> >> (lazy-seq >> (when-let [pseq (seq plseq)] >> >> >> (cons (new clojure.lang.MapEntry (first pseq) (v (first >> pseq))) >> >> >> (thisfn (rest pseq)))))) (keys pmap)))))) >> >> >> >> >> >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.