2010-07-23 94 views
2

我正在寫一個Clojure庫,我想知道設置庫的配置參數的最佳做法是什麼。如何在clojure庫中設置配置參數?

許多庫(如clojure-contrib中的庫)使用全局級參數,如*buffer-size*,用戶可以通過調用set!來設置它們。但是,這似乎不是對我來說最好的辦法,因爲它創造了一個全球化的國家,並且存在名稱衝突的可能性。

另一種方法是在每個依賴於它們的函數調用中傳遞參數。如果有很多參數,那麼可以使用它們的映射而不是傳遞單個參數。

作爲一個例子,假設我正在寫一個緩存庫。

使用第一種方式我有一個像*cache-size*, *expiry-time*, *cache-dir*等。用戶set!這幫全局參數(或不和讓他們默認)和像(set-in-cache id obj)(get-from-cache id)調用的函數。

使用第二種方法,用戶首先創建地圖參數,並將其傳遞給每一個電話

(def cache-parameters {:cache-size 1000 
         :expiry-time: 1440 
         :cache-dir "c:\\cache"}) 
(set-in-cache cache-parameters id obj) 
(get-from-cache cache-parameters id) 

所以這方法是用Clojure,爲什麼首選方法是什麼?

回答

3

其實你不能set!之類的東西c.c.io*buffer-size*除非你爲他們安裝了一個線程本地綁定與bindingwith-bindings等只是有一個針對本地線程綁定由較低級別的Clojure機械安裝瓦爾屈指可數,如*warn-on-reflection**read-eval*,使他們set! - 頂級;用戶定義的變量不是set! - 在頂層。 Var的根綁定可以用例如alter-var-root,intern, def,.bindRoot ...,但這應該謹慎使用。

至於可重新顯示的Vars與顯式參數問題的一部分:使用顯式參數幾乎總是可以的,通常更可取,因爲功能的可維護性增加了,這些功能清楚地顯示了它們依賴的所有數據。這就是說,如果某個配置可能會被設置一次,然後在應用程序/庫之後的任何函數調用中使用,那麼可能需要一些更具體的代碼來定義一個充滿吸引力的Var,並將其記錄下來並將配置文件在其中(這可能是在定義的窗體外改變Var的根綁定的罕見情況之一)。總結一下,如果不確定,在使用顯式參數傳遞的時候使用你的最佳判斷。

+0

最後一點*正是*我在clj-github和gotmilk中所做的。真棒知道我可能做了正確的事! – Rayne 2010-07-23 09:04:22

+0

'它可能會使更清晰的代碼來定義一個迷人的Var ...' 你能舉一個例子嗎? – 2010-07-23 11:37:57

+0

@Rayne:;-) @ abhin4v:其實你在問題中提到的'* buffer-size *'是一個使用Var來保存一個「合理的默認值」的好例子,它可能偶爾會被客戶端代碼反彈。至於重新綁定Var的根值,Congomongo(Clojure MongoDB庫)在名爲'* mongo-config *'Var的Var上使用'alter-var-root'(其用途正如名稱所示)。 – 2010-07-23 21:44:51