Clojure: dynamic import of java class

Suppose I define a clojure function like this:

(defn print-this [this] (println "print this: " this))

If I use the function in repl:

(print-this that)

I would finish:

print this: that
nil

as a conclusion.

Now, if I make this definition:

(defn import-by-name [name] (import (some.package.value name)))

and use the function in repl:

(import-by-name "SomeClassName")

I get

java.lang.ClassNotFoundException: some.package.value.name (NO_SOURCE_FILE:0)

where I would expect that instead of "name" instead of "SomeClassName" instead. If I print:

(import (some.package.value SomeClassName))

everything works as expected.

Why is this name [name] not interpreted in the import-by-name function above? Is it possible to dynamically import a java class from a variable value? If so, how? thanks!

+4
source share
1 answer

import is a macro, so any characters you pass to it will be taken literally.

(macroexpand '(import (some.package.value name)))

;; => (do (clojure.core/import* "some.package.value.name"))

literals

, , .

(defmacro import-by-name [name] `(import '[some.package.value ~name]))

(import-by-name "ClassName") ;; => nil

var .

(defn import-by-name [n]
  (.importClass (the-ns *ns*)
                (clojure.lang.RT/classForName (str "some.package.value." n))))

, , .

+4

All Articles