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
-~----------~----~----~----~------~----~------~--~---

Reply via email to