макрос, который создает объект в clojure - PullRequest
0 голосов
/ 22 сентября 2018

Я пытаюсь создать макрос, который динамически создает объекты Java в Clojure с аннотациями .

Я пробовал и proxy, и reify, но безуспешно, столкнулся с CompilerException.

Вот как далеко:

Proxy

Первая попытка была создать объект без макроса:

(.toString 
  (proxy [java.lang.Object] [] 
    (toString [] (str "proxyToString"))))

, что привело к: => "proxyToString"

, затем я попытался обернуть его макросом и передать object в качестве параметра:

(defmacro create-obj-with-proxy [klass]
  `(proxy [~klass] [] (toString [] (str "proxyToString"))))

, что приводит к: => #'oppose/create-obj-with-proxy

, и я могу расширить или оценить его

(macroexpand (create-obj-with-proxy java.lang.Object))
(.toString (create-obj-with-proxy java.lang.Object))

он также работает с reify.

(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)

Но если я связываю имя класса с переменной, я получаю исключения

(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:

Есть предложения?

Редактировать: благодаря @Michiel Borkent исправил объектвопрос создания.

1 Ответ

0 голосов
/ 22 сентября 2018

Вы почти у цели, но нужно удалить оператор сращивания:

(defmacro create-obj-with-proxy [klass]
  `(proxy [~klass] [] (toString [] (str "proxyToString"))))

Тогда

(create-obj-with-proxy java.lang.Object)

вернется

#object[dre.compress.proxy$java.lang.Object$ff19274a 0x6c221bc8 "proxyToString"]

Выпередавая в символ аргумент.С помощью unquote-splice вы пытаетесь воспринимать это как последовательность, которая не будет работать, поэтому возникает ошибка.

...