Last active
May 16, 2023 12:41
-
-
Save egamble/7781127 to your computer and use it in GitHub Desktop.
Two ways to call private methods in Clojure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This fn allows calling any method, as long as it's the first with that name in getDeclaredMethods(). | |
;; Works even when the arguments are primitive types. | |
(defn call-method | |
[obj method-name & args] | |
(let [m (first (filter (fn [x] (.. x getName (equals method-name))) | |
(.. obj getClass getDeclaredMethods)))] | |
(. m (setAccessible true)) | |
(. m (invoke obj (into-array Object args))))) | |
;; This function comes from clojure.contrib.reflect. A version of it is also in https://github.com/arohner/clj-wallhack. | |
;; It allows calling any method whose arguments have class types, but not primitive types. | |
(defn call-method | |
"Calls a private or protected method. | |
params is a vector of classes which correspond to the arguments to the method | |
obj is nil for static methods, the instance object otherwise. | |
The method-name is given a symbol or a keyword (something Named)." | |
[klass method-name params obj & args] | |
(-> klass (.getDeclaredMethod (name method-name) | |
(into-array Class params)) | |
(doto (.setAccessible true)) | |
(.invoke obj (into-array Object args)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment