让我们看一下 Leiningen 项目地图的真实示例:global-vars
:
;; Sets the values of global vars within Clojure. This example
;; disables all pre- and post-conditions and emits warnings on
;; reflective calls. See the Clojure documentation for the list of
;; valid global variables to set (and their meaningful values).
:global-vars {*warn-on-reflection* true
*assert* false}
它允许 leiningen 的用户在其项目范围内重新定义 Clojures 全局变量的默认值。
现在,如果此映射的键由关键字组成,我们将使用clojure.spec/keys
首先指定哪些键可以是映射的一部分,然后分别定义这些键下预期的值。但是由于clojure.spec/keys
默默地忽略了 and 中的非关键字:req
并为and:req-un
抛出异常(从 alpha15 开始),我们必须以某种方式解决这个问题。:opt
:opt-un
我们可以通过
(for [[sym varr] (ns-publics 'clojure.core)
:when (re-matches #"\*.+\*" (name sym))]
[varr (type @varr)])
=>
[*print-namespace-maps* java.lang.Boolean]
[*source-path* java.lang.String]
[*command-line-args* clojure.lang.ArraySeq]
[*read-eval* java.lang.Boolean]
[*verbose-defrecords* java.lang.Boolean]
[*print-level* nil]
[*suppress-read* nil]
[*print-length* nil]
[*file* java.lang.String]
[*use-context-classloader* java.lang.Boolean]
[*err* java.io.PrintWriter]
[*default-data-reader-fn* nil]
[*allow-unresolved-vars* java.lang.Boolean]
[*print-meta* java.lang.Boolean]
[*compile-files* java.lang.Boolean]
[*math-context* nil]
[*data-readers* clojure.lang.PersistentArrayMap]
[*clojure-version* clojure.lang.PersistentArrayMap]
[*unchecked-math* java.lang.Boolean]
[*out* java.io.PrintWriter]
[*warn-on-reflection* nil]
[*compile-path* java.lang.String]
[*in* clojure.lang.LineNumberingPushbackReader]
[*ns* clojure.lang.Namespace]
[*assert* java.lang.Boolean]
[*print-readably* java.lang.Boolean]
[*flush-on-newline* java.lang.Boolean]
[*agent* nil]
[*fn-loader* nil]
[*compiler-options* nil]
[*print-dup* java.lang.Boolean]
其余的我们可以通过阅读文档来填写。但是我的问题是:我们如何编写一个规范来确保如果映射包含键'*assert*
,它只会保存布尔值?