Reputation: 5598
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
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