动态加载别名的命名空间到另一个Clojure命名空间 [英] Dynamically loading an aliased namespace to another Clojure namespace

查看:124
本文介绍了动态加载别名的命名空间到另一个Clojure命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在运行时从文件加载命名空间。对于这个命名空间,我想有一个通用的别名,所以我可以从该命名空间访问函数,使用统一的限定名称,独立于加载文件的实际命名空间。

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.

示例(不工作):

;; 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`!!!

我已经尝试过各种操作( load-file load )并将 require 移动到不同的地方。没有运气到目前为止。

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

如何实现?

推荐答案

我认为问题是编译时的符号解析不能很好地与动态加载的命名空间。在你的例子中 bar / hello-world 是解析编译时,但是require在调用函数时动态完成。我不知道一个更漂亮的解决方案,但你可以尝试这样的:

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.

这篇关于动态加载别名的命名空间到另一个Clojure命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆