【问题标题】:Creating an alias to another Clojure namespace创建另一个 Clojure 命名空间的别名
【发布时间】:2012-07-31 08:23:48
【问题描述】:

我在一个命名空间中有一些私有函数,我想将它们包含在第二个命名空间中。例如

(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

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

此要求的原因如下:在命名空间one 中需要/使用该功能。 onetwo 的依赖项,并且由于我们不能有循环依赖项,因此在 two 本身内定义 foo 是行不通的。 two 是公共 API,因此 foo 需要公开成为 two 命名空间的一部分。

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

【问题讨论】:

  • 您希望别名相同还是可以是任何名称?
  • @Ankur - 目前希望使用相同的名称,但在某些情况下,创建具有不同名称的别名也可能很有用,因此如果解决方案允许这样做会很棒。
  • 试试这个:(def foo (with-meta one/foo (meta #'one/foo)))
  • 这引出了问题:为什么fooone 中?为什么它是私人的?显然它应该在two 和公共...
  • @kotarak - 好问题,在问题中添加了解释,但基本上是因为two 是公共 API。

标签: clojure namespaces


【解决方案1】:

这个怎么样:

(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 起别名后,您只需从先前的定义中挑选您想要保留的元数据。

【讨论】:

    【解决方案2】:

    Potemkin 库有一个函数 import-vars 来处理这种事情。

    https://github.com/ztellman/potemkin

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-05
      • 2023-03-21
      相关资源
      最近更新 更多