【问题标题】:Dynamically loading an aliased namespace to another Clojure namespace将别名命名空间动态加载到另一个 Clojure 命名空间
【发布时间】:2015-03-13 13:44:44
【问题描述】:

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

示例(不工作):

;; 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-fileload)并将require 移动到不同的地方。到目前为止没有运气。

我怎样才能做到这一点?

【问题讨论】:

  • 顺便说一句,我认为您的意思是 bar_a.clj 和 bar_b.clj。
  • 当然,修复它。谢谢

标签: clojure namespaces


【解决方案1】:

我认为问题在于符号的编译时解析不适用于动态加载的命名空间。在您的示例中,bar/hello-world 是在编译时解析的,但在调用函数时需要动态完成。我不知道对此有更漂亮的解决方案,但您可以尝试这样的方法:

(ns foo)

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

这当然不是很有效,因为每次调用函数时都会解析命名空间和函数符号。不过你应该能明白。

【讨论】:

  • 在 clojurescript 中这不起作用Arguments to require must be quoted. Offending spec: (symbol ns-name)
猜你喜欢
  • 1970-01-01
  • 2019-10-10
  • 2018-01-05
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2012-05-27
  • 1970-01-01
相关资源
最近更新 更多