2

Let's say I have come across a class with several static setter methods that I'd like to call in a row. The functionality I'm looking for is similar to that provided by doto, except that it must work on a class instead of an object:

(doto MyClass
      (setA "a")
      (setB "b"))

Unfortunately, when I try this, I get RuntimeException: Unable to resolve symbol: setA. Is there a special doto macro for classes?

0

2 Answers 2

2

I will leave this question open, since I'm hoping there's a better answer, but here's my home-grown macro to solve this problem:

(defmacro doto-class
  "Calls a series of static methods on a class"
  [klass & forms]
  (cons 'do
        (for [f forms]
          `(. ~klass ~f))))

which expands the example:

(macroexpand-1
 '(doto-class MyClass
              (setA "a")
              (setB "b")))

to

(do (. MyClass (setA "a"))
    (. MyClass (setB "b")))
Sign up to request clarification or add additional context in comments.

1 Comment

My brains fried from work, but I couldn't come up with anything, and the macro I wrote basically ended up looking like yours. I suspect this is such a rare use case that it wasn't considered. I don't think I've ever needed to sequence calls to a static method.
1

How do you call a static Java method from Clojure? Like this ...

(Classname/staticMethod args*)

For example,

> (System/getProperty "java.vm.version")

=> "25.141-b15"

We want a macro, say doto-static, that re-arranges this from (doto-static System (getProperty "java.vm.version")), and also allows a chain of calls.

Such a macro is ...

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

For example,

> (doto-static System (getProperty "java.vm.version") (getProperty "java.vm.version"))

=> "25.141-b15"

2 Comments

Interesting! Do you know if this macro provides benefits over the naive solution I posted earlier? If so, that'd make a great addition to this answer.
@user12341234 Yours is cleaner. The only advantage this possesses is to conform to the preferred syntax for static calls to Java. I hadn't got the point of your answer, or I wouldn't have posted this one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.