为另一个Clojure命名空间创建别名

时间:2012-07-31 08:23:48

标签: clojure namespaces

我在一个名称空间中有一些私有函数,我希望包含在第二个名称空间中。例如

(ns one)

(defn ^:private foo 
  "A docstring"
  [x] (* x 2))

第二个命名空间需要为此创建一个别名:

(ns two)

(def foo ???)

(foo 3)   ;; should work as if the function in namespace one was called
=> 6

理想情况下,我想保留docstring,所以我不必在两个地方维护它。此外,我想选择使用相同的名称或不同的名称。

此要求的原因如下:名称空间one中需要/使用该功能。 onetwo的依赖关系,由于我们不能拥有循环依赖关系,因此无法在foo内定义twotwo是公共API,因此foo需要公开成为two命名空间的一部分。

实现这一目标的最佳方式是什么?

2 个答案:

答案 0 :(得分:5)

这个怎么样:

(ns one)

(defn- foo 
  "A docstring"
  [x] (* x 2))

(ns two)

(def foo-alias #'one/foo)
(alter-meta! #'foo-alias merge (select-keys (meta #'one/foo) [:doc :arglists]))

诀窍是不解析符号'one / foo,因此避免在其元数据上触发私有标志。然后在第二个命名空间中使用foo别名后,您只需从先前的定义中选择要保留的元数据。

答案 1 :(得分:0)

Potemkin库有这种功能import-vars

https://github.com/ztellman/potemkin