Nils Blum-Oeste
Nils Blum-Oeste

Reputation: 5598

Dynamically loading an aliased namespace to another Clojure namespace

I am trying to load a namespace from a file during runtime. For this namespace I would like to have a common alias, so I can access functions from that namespace with a unified, qualified name independent from the actual namespace of the loaded file.

Example (not working):

;; bar_a.clj
(ns bar-a)
(defn hello-world [] "hello world a")

;; bar_b.clj
(ns bar-b)
(defn hello-world [] "hello world b")


;; foo.clj
(ns foo)

(defn init [ns-name]
  (let [ns-symbol (symbol ns-name)]
    (require `[ns-symbol :as bar])
    (bar/hello-world)))       ;; => No such var bar/hello world
                              ;;    during runtime when calling `init`!!!

I already tried various things (load-file, load) and moving the require to different places. No luck so far.

How can I achieve that?

Upvotes: 3

Views: 2138

Answers (1)

juhovh
juhovh

Reputation: 918

I think the problem is that compile-time resolution of symbols doesn't work well with dynamically loaded namespaces. In your example bar/hello-world is resolved compile-time but the require is done dynamically when the function is called. I don't know of a prettier solution to this, but you could try something like this:

(ns foo)

(defn init [ns-name]
  (require (symbol ns-name))
  (let [bar (find-ns (symbol ns-name))]
    ((ns-resolve bar 'hello-world))))

This is not very efficient of course, because both the namespace and the function symbol are resolved every time that function is called. But you should be able to get the idea.

Upvotes: 4

Related Questions