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

mik*_*era 5 namespaces clojure

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

(ns one)

(defn ^:private foo 
  "A docstring"
  [x] (* x 2))
Run Code Online (Sandbox Code Playgroud)

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

(ns two)

(def foo ???)

(foo 3)   ;; should work as if the function in namespace one was called
=> 6
Run Code Online (Sandbox Code Playgroud)

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

此要求的原因如下:命名空间中需要/使用该功能one.one是的依赖two,因为我们不能有循环依赖它不会工作定义footwo本身.two是公共API,因此foo需要公开成为two命名空间的一部分.

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

Jea*_*ano 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]))
Run Code Online (Sandbox Code Playgroud)

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