我可以引用另一个命名空间并将其函数公开为当前的ns吗?

Dam*_*ien 18 namespaces clojure

我想use会这样做,但似乎在当前命名空间中创建的映射不公开.这是我想要实现的一个例子:

(ns my-ns
  (:use [another-ns :only (another-fct)]))

(defn my-fct
  []
  (another-fct 123)) ; this works fine
Run Code Online (Sandbox Code Playgroud)

然后我有另一个这样的命名空间:

(ns my-ns-2
   (:require [my-ns :as my]))

(defn my-fct-2
  []
  (my/another-fct 456)) ; this doesn't work
Run Code Online (Sandbox Code Playgroud)

我想这样做是因为它another-ns是一个访问数据库的库.我想在单个命名空间(my-ns)中隔离对该库的所有调用,这样所有与数据库相关的函数都将在单个命名空间中隔离,并且如果需要,更容易切换到另一个数据库.

这个库的一些功能对我来说很好,但我想增加其他功能.假设读取函数很好,但我想通过一些验证来扩充写入函数.

到目前为止,我看到的唯一方法是将所有映射手动编码,my-ns即使对于我没有增加的功能也是如此.

Ale*_*ler 12

有选择地执行此操作(明确指定每个函数)的一种方法是使用类似Zach Tellman的Potemkin库.可以在lamina.core命名空间中找到它的一个使用示例,该命名空间用作Lamina的公共入口点,从所有其他内部命名空间导入关键公共函数.

你也可以使用clojure.contrib.def/defalias:

(use 'clojure.contrib.def/defalias)
(defalias foo clojure.string/blank?)
(foo "")
Run Code Online (Sandbox Code Playgroud)

  • 波将金很棒.我发现这比接受的答案更有帮助,它在宏上不起作用. (5认同)

Joh*_*den 9

这有帮助吗?

(defmacro pull [ns vlist]
  `(do ~@(for [i vlist]
           `(def ~i ~(symbol (str ns "/" i))))))
Run Code Online (Sandbox Code Playgroud)

这是一个例子:

(ns my-ns)

(defmacro pull [ns vlist]
  `(do ~@(for [i vlist]
           `(def ~i ~(symbol (str ns "/" i))))))

(pull clojure.string (reverse replace))

(defn my-reverse
  []
  (reverse "abc"))

(ns my-ns-2)

(defn my-fct-2 []
  (list (my-ns/my-reverse)
        (my-ns/reverse "abc")))

(my-fct-2)
Run Code Online (Sandbox Code Playgroud)

如果你想要拉入所有东西,那么:

(defmacro pullall [ns]
  `(do ~@(for [i (map first (ns-publics ns))]
           `(def ~i ~(symbol (str ns "/" i))))))

(pullall clojure.string)
Run Code Online (Sandbox Code Playgroud)