(ns demo.protectedfield
  [:gen-class
   :extends clojure.lang.ARef
   :exposes {validator {:get getvalidator :set setvalidator}}])

Is this what you are looking for?
After compile, you will get a class that extends clojure.lang.ARef

(compile 'demo.protectedfield)
(instance? clojure.lang.ARef (demo.protectedfield.))

and has a pair of public getter/setter.

(require '[clojure.reflect :refer [reflect]])
(->> (reflect demo.protectedfield)
  :members (filter (comp '#{getvalidator setvalidator} :name)))

({:name getvalidator,
  :return-type clojure.lang.IFn,
  :declaring-class demo.protectedfield,
  :parameter-types [],
  :exception-types [],
  :flags #{:public}}
 {:name setvalidator,
  :return-type void,
  :declaring-class demo.protectedfield,
  :parameter-types [clojure.lang.IFn],
  :exception-types [],
  :flags #{:public}})

Or, as the last resort, use reflection:

(defn field [^Class c name]
  (let [field (doto (.getDeclaredField c name) (.setAccessible true))]
    (fn
      ([] (.getType field))
      ([x] (.get field x))
      ([x v] (.set field x v)))))

(def validator
  (field clojure.lang.ARef "validator"))

Now, *validator* could get and set the corresponding protected field of 
clojure.lang.ARef:

(def forbid (constantly false))
(def permit (constantly true))

(let [v (atom 0)]
  (assert (nil? (get-validator v)))
  (assert (nil? (validator v)))
  (validator v permit)
  (assert (identical? permit (get-validator v)))
  (assert (identical? permit (validator v))))

-- 
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/d/optout.

Reply via email to