Parameters 如何在clojure库中设置配置参数?

Parameters 如何在clojure库中设置配置参数?,parameters,clojure,Parameters,Clojure,我正在编写Clojure库,我想知道设置库的配置参数的最佳实践是什么 许多库(如clojure contrib中的库)使用全局级参数,如*buffer size*,用户可以通过调用set在他们身上。但对我来说,这似乎不是最好的方式,因为它创建了一个全局状态,并且有名称冲突的可能性 另一种方法是在依赖于参数的每个函数调用中传递参数。如果有许多参数,则可以使用它们的映射,而不是传递单个参数 例如,假设我正在编写一个缓存库 使用第一种方法,我有全局参数,如*缓存大小*、*到期时间*、*缓存目录*等。用

我正在编写Clojure库,我想知道设置库的配置参数的最佳实践是什么

许多库(如clojure contrib中的库)使用全局级参数,如
*buffer size*
,用户可以通过调用
set在他们身上。但对我来说,这似乎不是最好的方式,因为它创建了一个全局状态,并且有名称冲突的可能性

另一种方法是在依赖于参数的每个函数调用中传递参数。如果有许多参数,则可以使用它们的映射,而不是传递单个参数

例如,假设我正在编写一个缓存库

使用第一种方法,我有全局参数,如
*缓存大小*、*到期时间*、*缓存目录*
等。用户
设置
s这些(或不是,并让它们成为默认值)并调用函数,如
(在缓存id obj中设置)
(从缓存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中,哪种方式是首选方式?为什么?

实际上,您无法
设置类似于
c.c.io
*缓冲区大小*
的东西,除非您使用
绑定为它们安装线程本地绑定
绑定
等。只有少数变量的线程本地绑定是由较低级别的Clojure机器安装的,例如
*反射警告*
*读取eval*
,使它们
设置-可在顶层使用;未设置用户定义的变量
-可在顶级执行。变量的根绑定可以通过以下方式进行更改:例如,
alter Var root
intern
def
.bindRoot
…,但应谨慎使用

至于可重新绑定的变量与显式参数,问题的一部分是:使用显式参数几乎总是可以的,而且通常更可取,这是因为函数的可维护性增加了,这些函数清楚地显示了它们所依赖的所有数据。这就是说,如果某个配置可能被设置一次,然后被应用程序/库中几乎所有的函数调用使用,那么更明智的代码可能会定义一个被屏蔽的Var,很好地记录它并将配置放入其中(这可能是极少数在定义表单之外更改Var的根绑定的情况之一)


总而言之,如果不确定,请使用您最好的判断——在显式参数传递方面出错。

最后一点正是我在clj github和gotmilk中所做的。知道我可能做了正确的事情真是太棒了!
让更理智的代码定义一个耳罩式变量可能会更明智……
您能举个例子吗?@Rayne:;-)@abhin4v:实际上,您在问题中提到的
*缓冲区大小*
是一个很好的例子,它使用Var来持有“合理的默认值”,这可能偶尔会被客户代码反弹。至于重新绑定Var的根值,Congomongo(Clojure MongoDB库)在名为
*mongo-config*
的Var上使用
alter Var-root
(其用途如名称所示)。谢谢。我使用
resolve
解决了我的问题。库的用户必须
def
一个特定的var,而我的库只能
解析它。@AbhinavSarkar从未见过库使用它。对你有用吗?您是如何处理名称空间问题并解决的?