Bamdad Dashtban
Bamdad Dashtban

Reputation: 354

a macro that creates object in clojure

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:

Proxy

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

Answers (1)

Michiel Borkent
Michiel Borkent

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

Related Questions