KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I'm writing a Clojure wrapper for the Braintree Java library to provide a more concise and idiomatic interface. I'd like to provide functions to instantiate the Java objects quickly and concisely, like: (transaction-request :amount 10.00 :order-id "user42") I know I can do this explicitly, as shown in this question : (defn transaction-request [& {:keys [amount order-id]}] (doto (TransactionRequest.) (.amount amount) (.orderId order-id))) But this is repetitive for many classes and becomes more complex when parameters are optional. Using reflection, it's possible to define these functions much more concisely: (defn set-obj-from-map [obj m] (doseq [[k v] m] (clojure.lang.Reflector/invokeInstanceMethod obj (name k) (into-array Object [v]))) obj) (defn transaction-request [& {:as m}] (set-obj-from-map (TransactionRequest.) m)) (defn transaction-options-request [tr & {:as m}] (set-obj-from-map (TransactionOptionsRequest. tr) m)) Obviously, I'd like to avoid reflection if at all possible. I tried defining a macro version of set-obj-from-map but my macro-fu isn't strong enough. It probably requires eval as explained here . Is there a way to call a Java method specified at runtime, without using reflection? Thanks in advance! Updated solution: Following the advice from Joost, I was able to solve the problem using a similar technique. A macro uses reflection at compile-time to identify which setter methods the class has and then spits out forms to check for the param in a map and call the method with it's value. Here's the macro and an example use: ; Find only setter m
Tags (comma-separated)
Save Edits
Cancel