【问题标题】:Is it possible to load-file in a namespace context?是否可以在命名空间上下文中加载文件?
【发布时间】:2018-01-18 13:35:13
【问题描述】:

我不知道我的标题是否清楚,但我想使用一个函数,它使用名称空间别名加载文件,而不需要堆栈的每个名称空间中的所有库。 为了更清楚,这是一个假代码:

我要加载的文件(“whatever.clj”):

{:my-fn (fn [a b] (ml/explode a b))}

定义阅读器的命名空间:

(ns my-project.reader
  (:require [my-lib.core :as ml]))

(defn load-definition-and-apply
  [a b]
  (let [{:keys [my-fn]} (load-file "whatever.clj")]
    (my-fn a b)))

所以如果我从my-project.reader 运行load-definition-an-apply,它将工作,因为ml/explode 已定义。 但现在想象一下,我从其他地方使用 load-definition-and-apply :

(ns my-project.processing
  (:require [my-project.reader :as rd]))

(rd/load-definition-and-apply 1 2)

将无法工作,因为在加载文件期间从 my-project.processing 中找不到 ml 别名。当我将代码包装在其他进程周围时也是如此。
解决办法是:

(ns my-project.processing
  (:require [my-lib.core :as ml]
            [my-project.reader :as rd]))

(rd/load-definition-and-apply 1 2)

这对于一个库来说是可以的,但我实际上导入了几个。有没有一种干净的方法可以不在塔的每个命名空间中导入读取文件所需的库,而只是为加载文件在概念上真正“执行”的命名空间调用它(这里:my-project.reader)?

我也不想加载 clj 文件,因为它被设计为对用户来说很简单。

谢谢

【问题讨论】:

  • 查看bindingin-ns 或沿着这些思路。我已经完成了,如果没有人回答我会的,只是现在没有时间。
  • 谢谢,我按照您的建议使用了绑定,并且成功了!

标签: clojure namespaces


【解决方案1】:

正如弗兰克 C. 所说的

(ns my-project.processing
  (:require [my-project.reader :as rd]))

(binding [*ns* (the-ns 'my-project.reader)]
  (rd/load-definition-and-apply 1 2))

【讨论】:

    【解决方案2】:

    我想你已经回答了你的问题。这个想法是使用 load-file 函数将 clojure 文件加载到当前命名空间中。

    正如我所见,在该文件中包含地图是没有意义的。只需将(def ...)(defn ...) 表格放在那里,就是这样。如果您知道任何可能的命名冲突,请在所有定义前加上一些前缀。

    我认为值得一提的是,这种动态加载代码的方式非常不明显,难以维护、调试等。最好只使用带有命名空间的普通文件。

    如果是重用代码的问题,只需将其作为独立库发布即可。

    【讨论】:

    • 您好,感谢您的意见。在这里,这些文件遵循规范,并且在某种程度上是功能规范。不创建名称空间的原因是因为文件树表示层次感,并且因为用户可以在其中添加与业务案例相对应的文件。所以这太“代码”而不能成为一个 EDN 文件,而且太“易变”而不能使用 def 或将其包含在代码中
    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 2018-10-16
    • 2013-06-26
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    相关资源
    最近更新 更多