Supposons que je veuille construire une grande bibliothèque clojure avec plusieurs composants. En tant que développeur, j'aimerais conserver plusieurs de ces composants dans des espaces de noms séparés, car de nombreuses fonctions d'aide peuvent avoir des noms similaires. Je ne veux pas nécessairement rendre les choses privées car elles peuvent avoir une utilité en dehors des cas extrêmes et les solutions de contournement derrière private ne sont pas bonnes. (En d'autres termes, j'aimerais suggérer l'utilisation du code, et non l'empêcher complètement).
Cependant, j'aimerais que les utilisateurs de la bibliothèque opèrent dans un espace de noms avec une union d'un sous-ensemble de nombreuses fonctions dans chaque sous-bibliothèque. Quelle est la meilleure façon idiomatique de procéder ? Une solution qui me vient à l'esprit est d'écrire une macro qui génère :requires et crée un nouveau mapping de var en définissant une liste donnée de noms de var (voir le premier exemple de code). Y a-t-il des compromis avec cette méthode, comme par exemple ce qui se passe avec l'extension des types ? Existe-t-il une meilleure méthode (ou une meilleure intégration) ?
Exemple de macro (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])
Encore une fois, pour clarifier, le but final serait d'avoir un fichier dans d'autres projets créés par les utilisateurs de mylib pour pouvoir faire quelque chose comme (src/someproject/core.clj) :
(ns someproject.core
(:require [mylib.public :as mylib]))
(mylib/mapper 'foo 'bar)
@Jeremy Wall, notez que la solution que vous proposez ne répond pas à mes besoins. Supposons que le code suivant existe.
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 : (Suppose que les chemins d'accès sont correctement définis)
(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
Si vous remarquez, les fonctions "using" dans mylib/public.clj NE PERMETTENT PAS à public.clj de FOURNIR ces variables au fichier utilisateur somerandomproject/core.clj.