So I realized that the method wasn't being found because args# is a
single argument, and I actually need it spliced in.

At this point I'm rather stuck. For example:

(defmacro make-msg-ewrapper [method-names]
  `(proxy [EWrapper] []
     ~@(map
        (fn [method-name]
          (let [args (gensym "args")]
           `(~(symbol method-name) [& args#]
             (println ~method-name ":"
                      (. EWrapperMsgGenerator ~(symbol method-name))
~@args#))))
        method-names)))

This doesn't work because args needs to be delayed until runtime
rather than macro-expand time. Would memfn work?

E.g. something like (apply (memfn tickPrice) EWrapperMsgGenerator
args)? Or does that only work for instance methods
(EWrapperMsgGenerator is static).

On Jun 18, 11:45 am, Jian Liu <liuj...@gmail.com> wrote:
> Hi David,
>
> Yes, the expansion I essentially want, and which runs properly without
> the macro:
>
> (proxy [EWrapper] []
>   (tickPrice [& args] (println "tickPrice" (. EWrapperMsgGenerator
> tickPrice args)))
>   (tickSize [& args] (println "tickSize" (. EWrapperMsgGenerator
> tickSize args)))
>   ... other methods
> )
>
> I resorted to a macro because there are 20-30 different methods, and
> if I wanted to write boilerplate all day I'd just do it in pure
> Java :)
>
> I'm sure there are other approaches like using reflection, or pulling
> out the inner (println ...) form into another macro, but this pretty
> well-defined.
>
> Thanks,
> Jian
>
> On Jun 18, 10:52 am, David Nolen <dnolen.li...@gmail.com> wrote:
>
>
>
>
>
>
>
> > On Fri, Jun 17, 2011 at 11:51 PM, Jian Liu <liuj...@gmail.com> wrote:
> > > Hi Clojure Gurus :)
>
> > > I've a somewhat contrived use-case for macros that I've been
> > > struggling with.
>
> > > Let's say there's an interface called EWrapper that I'm trying to
> > > implement with methods "tickPrice" and "tickSize", a concrete class
> > > EWrapperMsgGenerator that has methods with those names that return
> > > strings.
>
> > > I'd like to write a macro that proxies EWrapper's tickSize and
> > > tickPrice methods so that they print out the method name as well as
> > > the string returned from EWrapperMsgGenerator.
>
> > > E.g. (in java code):
> > > public tickSize( args ) { // on the proxied EWrapper
> > >  System.out.println( "tickSize: " +
> > > EWrapperMsgGenerator.tickSize( args ) )
> > > }
>
> > > Here's what I've come up with so far:
>
> > > (defmacro make-msg-ewrapper [method-names]
> > >  `(proxy [EWrapper] []
> > >    ~@(map
> > >       (fn [method-name]
> > >         `(~(symbol method-name) [& args#]
> > >           (println ~method-name ":"
> > >                    (. EWrapperMsgGenerator ~(symbol method-name)
> > > args#))))
> > >       method-names)))
>
> > > It's a bit messy -- I'm splicing in a map evaluation into proxy, and
> > > then writing in symbols in the function body. This works except that
> > > when I run the macro I get "No matching method: tickSize" referring to
> > > EWrapperMsgGenerator.
>
> > > The macro expansion looks like:
>
> > > (let* [p__4736__auto__ (new user.proxy$java.lang.Object$EWrapper
> > > $11bc5609)] (clojure.core/init-proxy p__4736__auto__ {tickPrice
> > > (clojure.core/fn ([this & args__2058__auto__] (clojure.core/println
> > > tickPrice : (. com.ib.client.EWrapperMsgGenerator tickPrice
> > > args__2058__auto__)))), list (clojure.core/fn ([this &
> > > args__2058__auto__] (clojure.core/println list : (.
> > > com.ib.client.EWrapperMsgGenerator list args__2058__auto__))))})
> > > p__4736__auto__)
>
> > > So far this looks fine to me, except that tickPrice within the
> > > EWrapperMsgGenerator call isn't scoped. Is there a better way to do
> > > this?
>
> > > Thanks,
> > > Jian
>
> > Do you have a working version of the code you want that doesn't involve a
> > macro?
>
> > David

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to