Вызвать серию статических методов Java из Clojure
Допустим, я наткнулся на класс с несколькими статическими методами установки, которые я хотел бы вызвать подряд. Функциональность, которую я ищу, похожа на ту, что предоставляется doto, за исключением того, что она должна работать с классом, а не с объектом:
(doto MyClass
(setA "a")
(setB "b"))
К сожалению, когда я пытаюсь это сделать, я получаю RuntimeException: Unable to resolve symbol: setA
, Есть ли особый doto
макрос для занятий?
2 ответа
Я оставлю этот вопрос открытым, так как надеюсь, что есть лучший ответ, но вот мой доморощенный макрос для решения этой проблемы:
(defmacro doto-class
"Calls a series of static methods on a class"
[klass & forms]
(cons 'do
(for [f forms]
`(. ~klass ~f))))
что расширяет пример:
(macroexpand-1
'(doto-class MyClass
(setA "a")
(setB "b")))
в
(do (. MyClass (setA "a"))
(. MyClass (setB "b")))
Как вы вызываете статический Java-метод из Clojure? Как это...
(Classname / staticMethod args *)
Например,
> (System/getProperty "java.vm.version")
=> "25.141-b15"
Мы хотим макрос, скажем doto-static
, который переупорядочивает это из (doto-static System (getProperty "java.vm.version"))
, а также разрешает цепочку звонков.
Такой макрос...
(defmacro doto-static [class-symbol & calls]
(let [qualify (fn [method-symbol] (->> method-symbol
(name)
(str (name class-symbol) \/)
(symbol)))
elaborate (fn [[method-symbol & arg-exprs]]
(cons (qualify method-symbol) arg-exprs))]
(cons 'do (map elaborate calls))))
Например,
> (doto-static System (getProperty "java.vm.version") (getProperty "java.vm.version"))
=> "25.141-b15"