Skip to content

Commit

Permalink
[#550] Implement subset of proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude committed Mar 12, 2021
1 parent 682fec6 commit 592488a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/sci/impl/proxy.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(ns sci.impl.proxy
{:no-doc true}
(:refer-clojure :exclude [proxy]))

(defn proxy [form _ _ctx classes _args & methods]
(let [abstract-class (first classes)
methods (into {}
(map (fn [meth]
[(list 'quote (first meth)) (list* 'fn (rest meth))])
methods))]
`(clojure.core/proxy* '~form ~abstract-class ~methods)))

(defn proxy*
[ctx _form abstract-class methods]
(if-let [pfn (:proxy-fn ctx)]
(pfn {:class abstract-class
:methods methods})
(throw (Exception. "no proxy-fn"))))
26 changes: 26 additions & 0 deletions test/sci/proxy_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(ns sci.proxy-test
(:require [clojure.test :refer [deftest is]]
[sci.core :as sci]))

(deftest APersistentMap-proxy-test
(let [obj (sci/eval-string
"
(proxy [clojure.lang.APersistentMap] []
(valAt
([k] [:k k])
([k default] [:k k :default default])))
"
{:classes {'clojure.lang.APersistentMap clojure.lang.APersistentMap}
:proxy-fn (fn [{:keys [:class :methods]}]
(case (.getName ^Class class)
"clojure.lang.APersistentMap"
(proxy [clojure.lang.APersistentMap] []
(valAt
([k] ((get methods 'valAt) k))
([k default] ((get methods 'valAt) k default))))))})]

(is (= [:k :f] (obj :f)))
(is (= [:k :f :default :def] (obj :f :def)))))



0 comments on commit 592488a

Please sign in to comment.