在其他名称空间中覆盖Clojure规范

时间:2019-09-19 01:30:01

标签: clojure clojure.spec

我想知道是否有一种方法可以从一个名称空间更改另一名称空间中的规范,并在后续规范中仍然保留该经修改的规范的使用。用例是进行覆盖的名称空间要创建一个变量nilable

作为一个简化的示例,假设核心名称空间具有以下规范:

(ns ns-test.core
  (:require [clojure.spec.alpha :as s]))

(s/def ::string-spec string?)

(s/def ::string-vec (s/coll-of ::string-spec))

然后,重写命名空间希望使用::string-vec规范,但希望使各个元素成为可字符串。当我以这种方式实现它时:

(ns ns-test.override
  (:require [clojure.spec.alpha :as s]
            [ns-test.core       :as c]))

(prn "1" (s/valid? ::c/string-vec ["s"]))
(prn "2" (s/valid? ::c/string-vec [nil]))

(in-ns 'ns-test.core)

(s/def ::string-spec (s/nilable string?))

(in-ns 'ns-test.override)

(prn "3" (s/valid? ::c/string-vec ["s"]))
(prn "4" (s/valid? ::c/string-spec nil))
(prn "5" (s/valid? ::c/string-vec [nil]))

它更改了::c/string-spec而不是::c/string-vec,并且我不想复制所有相关的规范并重新定义它们,因为它们除了使用的单个var以外,其他定义都没有改变。在许多其他地方。

"1" true                                                                                                                                                                                                    
"2" false                                                                                                                                                                                                
#namespace[ns-test.core]
:ns-test.core/string-spec
#namespace[ns-test.override]
"3" true                                                                                                                                                                        
"4" true                                                                                                                                                                                                 
"5" false                                                                                                                                                                                                

有什么办法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

此行为与名称空间无关 规格不应在运行时更改。 如果需要在更换时进行更改,则需要重新加载/重新定义所有规格。