【问题标题】:How to set configuration parameters in clojure library?如何在 clojure 库中设置配置参数?
【发布时间】:2010-07-23 06:43:16
【问题描述】:

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

许多库(例如 clojure-contrib 中的库)使用全局级别参数,例如 *buffer-size*,用户可以通过在它们上调用 set! 来设置这些参数。但这对我来说似乎不是最好的方法,因为它会创建一个全局状态并且有可能发生名称冲突。

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

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

使用第一种方法,我有*cache-size*, *expiry-time*, *cache-dir* 等全局参数。用户set!s 这些(或不让它们成为默认值)并调用(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 中哪种方式是首选方式,为什么?

【问题讨论】:

    标签: parameters clojure


    【解决方案1】:

    实际上,你不能 set! c.c.io*buffer-size* 之类的东西,除非你使用 bindingwith-bindings 等为它们安装线程本地绑定。只有少数 Vars 可以用于线程本地绑定由较低级别的 Clojure 机器安装,例如 *warn-on-reflection**read-eval*,使它们 set!-能够在顶层;用户定义的 Var 在顶层不是 set!-able。 Var 的根绑定可以通过例如更改alter-var-rootinterndef.bindRoot ...,但应该谨慎使用。

    至于问题的可重新绑定变量与显式参数部分:使用显式参数几乎总是可以的,而且通常更可取,因为函数的可维护性提高了,这些函数清楚地显示了它们所依赖的所有数据片段。话虽如此,如果某些配置可能只设置一次,然后被应用程序/库中的几乎每个函数调用使用,它可能会使代码更清晰地定义一个耳罩 Var,将其记录好并放置配置在其中(这可能是在定义的表单之外更改 Var 的根绑定的罕见情况之一)。

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

    【讨论】:

    • 最后一点正是我在 clj-github 和 gotmilk 中所做的。很高兴知道我可能做对了!
    • it might make for saner code to define an earmuffed Var ...你能举个例子吗?
    • @Rayne: ;-) @abhin4v: 实际上你在问题中提到的*buffer-size* 是使用 Var 保持“合理默认值”的一个很好的例子,它可能偶尔会被客户端代码反弹.至于重新绑定 Var 的根值,Congomongo(Clojure MongoDB 库)在名为 *mongo-config* 的 Var 上使用 alter-var-root(其用途正如其名称所暗示的那样)。
    • 谢谢。我通过使用resolve 解决了我的问题。库的用户必须 def 一个特定的 var 而我的库只需 resolves 它。
    • @AbhinavSarkar 从未见过图书馆使用它。它对你有用吗?您是如何处理和解决命名空间问题的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2015-08-16
    相关资源
    最近更新 更多