0

有人可以阐明以下行为吗?

假设我有一个带有规范的命名空间:

(ns user.specs
  (:require [clojure.alpha.spec :as s]
            [clojure.alpha.spec.gen :as gen]
            [clojure.string :as str]))


# Non-blank string of 20 to 50 ascii chars.
(s/def ::text (s/with-gen
                (s/and string? #(not (str/blank? %)))
                #(gen/such-that
                   (complement str/blank?)
                   (gen/fmap
                     clojure.string/join
                     (gen/vector
                       (gen/char)
                       20 50)))))

现在我想重用这个规范。

(in-ns 'user)

(require '[user.specs :as su])
=> nil

(def kws [::dir
          ::ns])
=> #'user/kws

(s/def ::dir ::su/text)
=> :user/dir

(s/def ::ns string?)
=> :user/ns

(s/register ::spec (s/schema* kws))
=> :user/spec

执行最后一个规范时,出现错误:

(s/exercise ::spec)
Error printing return value (IllegalArgumentException) at clojure.core/-cache-protocol-fn (core_deftype.clj:583).
No implementation of method: :conform* of protocol: #'clojure.alpha.spec.protocols/Spec found for class: clojure.lang.Keyword

但是,如果我重新定义::dir规范使用s/registers/get-spec不是s/def,没问题:

(s/register ::dir (s/get-spec ::su/text))
=> :user/dir

(s/exercise ::spec)
=>
([#:user{:dir "teôÆ>EüáéNj¬u}zþs²DÍ$", :ns ""}
  #:user{:dir "teôÆ>EüáéNj¬u}zþs²DÍ$", :ns ""}]
 [#:user{:dir ":éû,@Î|)Q«óCS\t´ÿ4ÚÝܺ»Ân5Zq", :ns ""}
  #:user{:dir ":éû,@Î|)Q«óCS\t´ÿ4ÚÝܺ»Ân5Zq", :ns ""}]
... elided

我假设,从错误消息中,使用s/def, spec 解析::dir为文字::su/text关键字而不是关联的规范。

1)为什么?
2) s/register+s/get-spec是一个合适的解决方案吗?

我正在尝试在域特定名称下的几个地方重用“实用程序”规范。

FWIW,我正在使用 spec-alpha2 来动态构建规范并从schema+中受益select

4

1 回答 1

1

别名规范(s/def ::dir ::su/text)目前在规范 2 中不起作用,这仍在进行中。

于 2020-04-27T01:41:29.753 回答