2010-07-23 56 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

相关问题