Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 314
Nils Blum-Oeste Avatar asked Jan 26 '26 04:01

Nils Blum-Oeste


1 Answers

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.

like image 179
juhovh Avatar answered Jan 28 '26 16:01

juhovh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!