Dynamically loading an aliased namespace to another Clojure namespace

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

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?

回答1:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!