Могу ли я сослаться на другое пространство имен и представить его функции как общедоступные для текущих ns? - PullRequest
16 голосов
/ 19 января 2011

Я думал, что 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 даже для функцийЯ не увеличиваю.

Ответы [ 3 ]

12 голосов
/ 19 января 2011

Один из способов сделать это выборочно (указав каждую функцию явно) - использовать что-то вроде библиотеки Потемкина Зака ​​Телмана .Пример его использования можно найти в пространстве имен lamina.core , которое служит общедоступной точкой входа для Lamina, импортируя ключевые открытые функции из всех других внутренних пространств имен.

Вы также можете использовать clojure.contrib.def / defalias :

(use 'clojure.contrib.def/defalias)
(defalias foo clojure.string/blank?)
(foo "")
9 голосов
/ 20 января 2011

Это помогает?

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

Вот пример:

(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)

Если вы хотите просто вытянуть все, то:

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

(pullall clojure.string)
1 голос
/ 01 сентября 2016

Чтобы извлечь все из пространства имен, в котором могут быть определены макросы, используйте

(defmacro pullall [ns]
  `(do ~@(for [[sym var] (ns-publics ns)]
           `(def ~sym ~var))))
...