Issue
I'm new to Clojure and have created a simple macro to call certain methods on a Java class and return results into a Clojure map and this all works fine. (Also i'm aware of the bean
function however the classes I'm using aren't beans).
My question is in regard to the calling code. Is it better form to pass the Java 'methods' as symbols?
I'm not even sure what type .toString
is at the moment (in the calling code)? It all works but not sure its idiomatic Clojure.
(defmacro obj-to-map
[obj & body]
(let [afn (fn [[method kw]]
`(~kw (~method ~obj)))]
`(assoc {} ~@(mapcat afn (partition 2 body)))))
(obj-to-map "hello" .length :length .toString :value)
=> {:value "hello", :length 5}
Solution
The .toString
etc are symbols in the calling code.
I think it would be better to pass the method name and invoke it using ".".
(defmacro obj-to-map
[obj & body]
(let [afn (fn [[method kw]]
`(~kw (. ~obj ~method)))]
`(assoc {} ~@(mapcat afn (partition 2 body)))))
(obj-to-map "hello" length :length toString :value)
=> {:value "hello", :length 5}
Answered By - Alex Miller
Answer Checked By - Willingham (JavaFixing Volunteer)