Reputation: 354
I'm trying to create a macro that dynamically creates java objects in Clojure with annotations.
I've been trying both proxy
and reify
with no success facing CompilerException
.
Here is as far as got:
fist attempt was to create an object without a macro:
(.toString
(proxy [java.lang.Object] []
(toString [] (str "proxyToString"))))
which results to : => "proxyToString"
then i tried to wrap it with a macro and pass the object
as parameter:
(defmacro create-obj-with-proxy [klass]
`(proxy [~klass] [] (toString [] (str "proxyToString"))))
which results to : => #'oppose/create-obj-with-proxy
and i can expand or evaluate it
(macroexpand (create-obj-with-proxy java.lang.Object))
(.toString (create-obj-with-proxy java.lang.Object))
it works with reify as well.
(defmacro create-obj-with-reify [klass]
`(reify ~klass
(toString [this] "reifyToString")))
(macroexpand (create-obj-with-reify java.lang.Object))
(.toString (create-obj-with-proxy java.lang.Object)
But if i associate the class name to a variable, i get exceptions
(def give-me-class java.lang.Object)
(def give-me-class-fn [] java.lang.Object)
(.toString (create-obj-with-proxy give-me-class))
(.toString (create-obj-with-proxy (give-me-class-fn)))
(.toString (create-obj-with-proxy give-me-class))
CompilerException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class, compiling:
(.toString (create-obj-with-proxy (give-me-class-fn)))
CompilerException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol, compiling:
Any suggestions ?
Edit: thanks to @Michiel Borkent fixed the object creation issue.
Upvotes: 0
Views: 174
Reputation: 34820
You're almost there, but need to remove the splicing operator:
(defmacro create-obj-with-proxy [klass]
`(proxy [~klass] [] (toString [] (str "proxyToString"))))
Then
(create-obj-with-proxy java.lang.Object)
will return
#object[dre.compress.proxy$java.lang.Object$ff19274a 0x6c221bc8 "proxyToString"]
You're passing in a symbol argument. With unquote-splice you're trying to treat that as a sequence, which won't work, hence the error.
Upvotes: 1