假设我想要构建一个包含多个组件的大型clojure库。作为一名开发人员,我想将许多组件保存在不同的名称空间中,因为许多助手函数可能具有相似的名称。我不一定要把事情私人化,因为他们在极端情况下可能具有外部效用,并且隐私背后的解决方案并不好。 (换句话说,我想建议代码的使用,而不是完全阻止使用。)如何在构建公共消费的clojure库时组织函数名称?
但是,我希望库的用户在一个命名空间中操作的联合的许多功能的子集每个子库。什么是地道或最好的方式来做到这一点?我想到的一个解决方案是编写一个生成以下代码的宏:通过定义给定的var名称列表来请求并创建一个新的var映射(请参阅第一个代码示例)。这种方法是否存在折衷,如扩展类型会发生什么?有没有更好的方法(或内置)?
宏示例中(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)
@Jeremy墙,请注意您提出的解决方案并不fullfill我的需要。让我们假设存在以下代码。
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。
好的答案。我曾尝试过compojure.core风格,但遇到了你提到的限制,所以我一直在寻找潜在的替代品,我会在接受之前调查叶片并了解它是如何工作的 – bmillare
Cascalog按照类似的方式组织但不太严格 - 您需要的许多主要内容是在cascalog.api ns中或者是别名,但您也可以访问底层ns的更高级功能。 –