How do I factor code setting many different fields in a Java object? I would like to factor
(set! (. employee name) "Chris")
(set! (. employee age) 100)
(set! (. employee salary) 5000)
to
(doseq [field '((name "Chris") (age 100) (salary 5000))]
(set! (. employee (first field)) (second field)))
However this won't work because the period is a macro, and tries to evaluate (first field) literally. By the way, I understand that setting fields is not good practice. I need to inter-operate with legacy code.
Try to use setters - but if you have no choice and really need to factor this out, a macro like this would do:
(defmacro set-all [object & fields-and-values]
(let [obj-sym (gensym)]
`(let [~obj-sym ~object]
~@(for [[field value] (partition 2 fields-and-values)]
`(set! (. ~obj-sym ~field)
~value)))))
The gensym is needed in case the expression yielding object has any side effects.
Example usage:
user> (def p (java.awt.Point.))
#'user/p
user> (set-all p x 4 y 5)
5
user> p
#<Point java.awt.Point[x=4,y=5]>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With