Вызвать серию статических методов 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"
Другие вопросы по тегам