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