Допустим, я хочу создать большую библиотеку clojure с несколькими компонентами.Как разработчик, я хотел бы хранить многие компоненты в отдельных пространствах имен, поскольку многие вспомогательные функции могут иметь похожие имена.Я не хочу делать вещи частными, так как в крайних случаях они могут быть полезны снаружи, а обходной путь за частной не очень хорош.(Другими словами, я хотел бы предложить использование кода, а не полностью предотвратить его использование.)
Однако я бы хотел, чтобы пользователи библиотеки работали в пространстве имен с объединением подмножества многих изфункции в каждой подбиблиотеке.Какой идиоматический или лучший способ сделать это?Одно из решений, которое мне приходит в голову, - написать макрос, который генерирует: требует и создает новое отображение вар, определяя заданный список имен вар (см. Первый пример кода).Есть ли компромиссы с этим методом, например, что происходит с расширяющимися типами?Есть ли лучший способ (или встроенный)?
Пример макроса (src / mylib / public.clj):
(ns mylib.public
(:require [mylib.a :as a])
(:require [mylib.b :as b]))
(transfer-to-ns [+ a/+
- b/-
cat b/cat
mapper a/mapper])
Опять же, чтобы уточнить, конечной целью будет иметь некоторый файл в других проектах, созданных пользователями mylib длябыть в состоянии сделать что-то вроде (src / someproject / core.clj):
(ns someproject.core
(:require [mylib.public :as mylib]))
(mylib/mapper 'foo 'bar)
@ Джереми Уолл, обратите внимание, что предложенное вами решение не полностью отвечает моим потребностям.Предположим, существует следующий код:
mylib / a.clj:
(ns mylib.a)
(defn fa [] :a)
mylib / b.clj:
(ns mylib.b)
(defn fb [] :b)
mylib / public.clj:
(ns mylib.public
(:use [mylib.a :only [fa]])
(:use [mylib.b :only [fb]]))
somerandomproject / core.clj: (Предположим, что пути к классам установлены правильно)
(ns somerandomproject.core
(:require [mylib.public :as p])
;; somerandomproject.core=> (p/fa)
;; CompilerException java.lang.RuntimeException: No such var: p/fa, compiling: (NO_SOURCE_PATH:3)
;; somerandomproject.core=> (mylib.a/fa)
;; :a
Если вы заметили, «использование» функций в mylib / public.clj НЕ ДОПУСКАЕТ public.cljПРЕДОСТАВИТЬ эти переменные в пользовательский файл somerandomproject / core.clj.