proxy + protocols

This commit is contained in:
Michiel Borkent 2021-03-13 17:25:24 +01:00
parent c0e512e304
commit a426cddd4a
3 changed files with 22 additions and 8 deletions

2
sci

@ -1 +1 @@
Subproject commit 139df5af5ab8e80a4988db45f1c7110ff40f3e8f Subproject commit bf0fc870e5d9060ea79dd49594487d600bb64571

View file

@ -15,11 +15,17 @@
(defn class-name [^Class clazz] (defn class-name [^Class clazz]
(.getName clazz)) (.getName clazz))
(defn proxy-fn [{:keys [class interfaces methods]}] (defn proxy-fn [{:keys [class interfaces protocols methods]}]
(let [interfaces (set (map class-name interfaces))] (let [interfaces (set (map class-name interfaces))]
(case [(class-name class) interfaces ] (case [(class-name class) interfaces ]
["clojure.lang.APersistentMap" #{"clojure.lang.IMeta" "clojure.lang.IObj"}] ["clojure.lang.APersistentMap" #{"clojure.lang.IMeta" "clojure.lang.IObj"}]
(proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj] [] (proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj sci.impl.types.IReified] []
(getInterfaces []
interfaces)
(getMethods []
methods)
(getProtocols []
protocols)
(iterator [] ((method-or-bust methods 'iterator) this)) (iterator [] ((method-or-bust methods 'iterator) this))
(containsKey [k] ((method-or-bust methods 'containsKey) this k)) (containsKey [k] ((method-or-bust methods 'containsKey) this k))
(entryAt [k] ((method-or-bust methods 'entryAt) this k)) (entryAt [k] ((method-or-bust methods 'entryAt) this k))

View file

@ -12,6 +12,8 @@
(def code (def code
'(do '(do
(require '[clojure.core.protocols])
(require '[clojure.datafy :as d])
(defn auto-deref (defn auto-deref
"If value implements IDeref, deref it, otherwise return original." "If value implements IDeref, deref it, otherwise return original."
[x] [x]
@ -21,7 +23,7 @@
(defn proxy-deref-map (defn proxy-deref-map
{:added "1.0"} {:added "1.0"}
[m] [m]
(proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj] (proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj clojure.core.protocols.Datafiable]
[] []
(iterator [] (iterator []
::TODO) ::TODO)
@ -39,7 +41,9 @@
(key [] k) (key [] k)
(val [] (auto-deref (get m k))))) m)) (val [] (auto-deref (get m k))))) m))
(withMeta [md] (proxy-deref-map (with-meta m md))) (withMeta [md] (proxy-deref-map (with-meta m md)))
(meta [] (meta m)))) (meta [] (meta m))
(datafy [] {:datafied true})))
(let [m (proxy-deref-map (let [m (proxy-deref-map
{:a (delay 1) {:a (delay 1)
:b (delay 2) :b (delay 2)
@ -58,11 +62,15 @@
(contains? :a)) (contains? :a))
(seq m) (seq m)
(meta (with-meta m {:a 1})) (meta (with-meta m {:a 1}))
]))) (d/datafy m)
,])))
(require 'clojure.pprint)
(deftest APersistentMap-proxy-test (deftest APersistentMap-proxy-test
(is (= [1 2 3 true [:c 3] (is (= [1 2 3 true [:c 3]
5 3 5 false 5 3 5 false
'([:a 1] [:b 2] [:c 3]) '([:a 1] [:b 2] [:c 3])
{:a 1}] {:a 1}
(bb code)))) {:datafied true}]
(bb (with-out-str (clojure.pprint/pprint code))))))