假設我想要構建一個包含多個組件的大型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的更高級功能。 –