mybuddymichael
mybuddymichael

Reputation: 1710

Can you force a Clojure macro to evaluate its arguments?

I'm trying to define a helper function that wraps clojure.test/deftest. Here's my general idea:

(defn test-wrapper
  [name & body]
  (deftest (symbol (clojure.string/replace name #"\W" "-")) body)))

However, since the first argument to deftest is unevaluated, it throws an exception since it is a form and not a symbol. Is there any way to force the form to evaluate first?

Upvotes: 4

Views: 594

Answers (2)

Michiel Borkent
Michiel Borkent

Reputation: 34870

The better approach here is to make test-wrapper a macro. Macros don't evaluate their arguments, unless you tell them to. You can manipulate the arguments and substitute them in some generated code, as follows:

(use 'clojure.test)

(defmacro test-wrapper
  [name & body]
  (let [test-name (symbol (clojure.string/replace name #"\W" "-"))]
    `(deftest ~test-name ~@body)))

(test-wrapper "foo bar" (is (= 1 1)))

(run-tests)

Upvotes: 4

sepp2k
sepp2k

Reputation: 370455

There's no way to make a macro (that you didn't write) evaluate its arguments.

The best way to make your test-wrapper do what you want it to would be to turn it into a macro itself. Then it could evaluate the call to symbol itself and then expand to a call to deftest with the result of the call to symbol as the first argument.

Upvotes: 4

Related Questions