定义多个变量的Clojure宏

6

我有一个Clojure应用程序,需要一些配置变量,主要是字符串,但也有需要计算的内容。

我可以通过类似以下方式声明每个变量:

(def config-db "URI_DB"))
(def config-time (hours 1))

但我认为编写一个宏来实现这个功能可能是一个好主意(我不太确定),宏的样子应该像这样:

(make-config 
  config-db "URI_DB"
  config-time (hours 1))

(或者我可以将名称放入向量中,让它看起来更像 let 语句)
但是当我放置多个组合时,出现了问题,我尝试了这样做:
(defmacro define-config
  [name definition]
  `(def ~name ~definition))

但我不知道如何将其扩展为更有用的内容...

有任何建议或想法吗?


我知道这很老,但是你的用例似乎更适合使用地图进行支持,例如 (def config {:db "URI_DB" :time (hours 1)}) - eyelidlessness
1个回答

10

我强烈建议单独对每个def进行处理。这个宏虽然很简单,但并不是很有用。当某人看到def时,他们确切地知道正在发生什么。当他们看到您的自定义make-config调用时,他们必须查看make-config的实现才能知道正在发生什么。在大型示例中减少一些字符会降低可读性。

话虽如此,你可以轻松地使用宏来实现这一点:

(defmacro make-config [& forms]
  `(do ~@(for [[name body] (partition 2 forms)]
           `(def ~name ~body))))

还有一个使用示例:

user=> (make-config foo "foo" bar (str "b" "a" "r"))
#'user/bar
user=> foo
"foo"
user=> bar
"bar"

啊,如果他把它叫做 setq,每个普通的Lisper都会知道他的意思。 - amalloy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接