我不知道我的标题是否清晰,但我想使用一个函数,该函数使用命名空间别名加载文件,而不需要堆栈的每个命名空间中的所有libarires。 为了更清楚,这是一个假代码:
要加载的文件(" 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)))
因此,如果我从load-definition-an-apply
运行my-project.reader
,那么它将在定义ml/explode
后生效。
但现在想象一下,我在其他地方使用load-definition-and-apply:
(ns my-project.processing
(:require [my-project.reader :as rd]))
(rd/load-definition-and-apply 1 2)
无法正常运行,因为在加载文件期间ml
找不到my-project.processing
别名。当我将代码包装在其他进程周围时,这是相同的
解决方案是:
(ns my-project.processing
(:require [my-lib.core :as ml]
[my-project.reader :as rd]))
(rd/load-definition-and-apply 1 2)
哪个库可以,但我实际上导入了几个。是否有一种干净的方法可以不在塔的每个命名空间中导入所需的库来读取文件,只需将其称为命名空间,其中load-file实际上是概念性的"执行" (这里:my-project.reader
)?
我不想加载clj文件,因为它的设计对用户来说很简单。
由于
答案 0 :(得分:1)
正如Frank 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))
答案 1 :(得分:1)
我想你已经回答了你的问题。我们的想法是使用load-file函数将clojure文件加载到当前名称空间中。
正如我所见,没有任何意义在该文件中包含地图。只需添加(def ...)
和(defn ...)
表单即可。如果您知道任何可能的命名冲突,请在前缀之前添加所有定义。
我认为值得一提的是这种加载代码的方式非常不明显,难以维护,调试等。最好只使用带有命名空间的普通文件。
如果是重用代码的问题,请将其作为独立库发布。