2011-01-02 4 views
9

¿Cómo factoro el código al configurar muchos campos diferentes en un objeto Java? Me gustaría que factorCódigo del factor Clojure que establece muchos campos diferentes en un objeto Java

(set! (. employee name) "Chris") 
(set! (. employee age) 100) 
(set! (. employee salary) 5000) 

a

(doseq [field '((name "Chris") (age 100) (salary 5000))] 
    (set! (. employee (first field)) (second field))) 

Sin embargo, esto no funcionará porque el periodo es una macro, y trata de evaluar (primer campo), literalmente. Por cierto, entiendo que establecer campos no es una buena práctica. Necesito interoperar con el código heredado.

Respuesta

7

intenta utilizar los emisores - pero si usted tiene otra opción y realmente necesita factor esto, una macro como esta haría:

(defmacro set-all [object & fields-and-values] 
    (let [obj-sym (gensym)] 
    `(let [~obj-sym ~object] 
     [email protected](for [[field value] (partition 2 fields-and-values)] 
      `(set! (. ~obj-sym ~field) 
        ~value))))) 

El gensym es necesario en caso de que el objeto de expresión de expresión tenga algún efecto secundario.

Ejemplo de uso:

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]> 
5

Usted puede tratar de:

(defmacro set-all! [obj m] 
    `(do [email protected](map (fn [e] `(set! (. ~obj ~(key e)) ~(val e))) m) ~obj)) 

Ejemplo:

(def a (java.awt.Point.)) 
(set-all! a {x 300 y 100}) 

macroexpand-todo:

(do (set! (. a x) 9) 
    (set! (. a y) 7) 
    a) 
+0

No existen tales métodos. – chris

+0

Ah, estás configurando campos. Mi culpa por no prestar atención. Actualicé mi respuesta. – Psyllo

Cuestiones relacionadas