Могу ли я ссылаться на другое пространство имен и публиковать его функции для текущих ns?
Я думал, что use
сделает это, но похоже, что отображение, созданное в текущем пространстве имен, не является общедоступным. Вот пример того, что я хотел бы достичь:
(ns my-ns
(:use [another-ns :only (another-fct)]))
(defn my-fct
[]
(another-fct 123)) ; this works fine
Тогда у меня есть другое пространство имен, подобное этому:
(ns my-ns-2
(:require [my-ns :as my]))
(defn my-fct-2
[]
(my/another-fct 456)) ; this doesn't work
Я хотел бы сделать это, потому что another-ns
- это библиотека для доступа к базе данных. Я хотел бы выделить все вызовы в эту библиотеку в одном пространстве имен (my-ns
), таким образом все зависимые от БД функции будут изолированы в одном пространстве имен, и при необходимости будет проще переключиться на другой БД.
Некоторые из функций этой библиотеки прекрасно подходят для меня, но я хотел бы увеличить других. Пусть говорят, что функции чтения прекрасны, но я хотел бы увеличить функции записи с некоторой проверкой.
Единственный способ, который я вижу до сих пор, - вручную переписать все сопоставление в my-ns
даже для функций, которые я не увеличиваю.
Ответы
Ответ 1
Помогает ли это?
(defmacro pull [ns vlist]
`(do [email protected](for [i vlist]
`(def ~i ~(symbol (str ns "/" i))))))
Вот пример:
(ns my-ns)
(defmacro pull [ns vlist]
`(do [email protected](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)
Если вы хотите просто втянуть все, то:
(defmacro pullall [ns]
`(do [email protected](for [i (map first (ns-publics ns))]
`(def ~i ~(symbol (str ns "/" i))))))
(pullall clojure.string)
Ответ 2
Один из способов сделать это выборочно (явно указывая каждую функцию) - использовать что-то вроде Zach Tellman Библиотека Потемкина. Пример его использования находится в lamina.core пространстве имен, который служит точкой публичной точки для Lamina, импортируя ключевые публичные функции из всех других внутренние пространства имен.
Вы также можете использовать clojure.contrib.def/defalias:
(use 'clojure.contrib.def/defalias)
(defalias foo clojure.string/blank?)
(foo "")
Ответ 3
Чтобы вытащить все из пространства имен, которые могут иметь макросы, определенные внутри, используйте
(defmacro pullall [ns]
`(do [email protected](for [[sym var] (ns-publics ns)]
`(def ~sym ~var))))