Hi,
On 27 Okt., 21:08, Matt Moriarity <[EMAIL PROTECTED]> wrote:
> I am trying to write a macro to rewrite something like this:
>
> (set-props my-jframe :title "blah" :visible true)
>
> Into calls to the setter methods. I finally settled on this:
>
> (defmacro set-props [obj & props]
> (let [prop-map (apply hash-map props)]
> `(do
> ~(for [[key val] prop-map]
> `(~(keyword-to-method key) ~obj ~val))
> ~obj)))
>
> where keyword-to-method just converts :title into .setTitle.
> ...
> how can i make this work?
You probably don't need a macro here.
(use '[clojure.contrib.fcase :only (case)])
(defn keyword-to-method
[kw]
(case kw
:title #(. %1 setTitle %2)
:visible #(. %1 setVisible %2)))
(defn set-props
[obj & props]
(do
(doseq [k v] (partition 2 props)
((keyword-to-method k) obj v))
obj))
This is a pretty naive implementation, but it should probably
work.
Just a note about your macro. You should not insert the same
value several times. It will be evaluated several times. Imagine
you call your macro as (set-props (new JFrame) ...). The object
actually returned is a different JFrame!
The correct way is to use a let.
(defmacro xxx
[obj]
`(let [obj# ~obj]
(do-stuff-with obj#)
(and-more-stuff obj#)))
Now the obj is just evaluated once. symbol# is a short way to
generate a unique symbol, which can be used to cache the value.
Hope this helps.
Sincerely
Meikel
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---