简体   繁体   中英

How can I get a Clojure Spec as an object?

I want to look at the data-structure which represents a Clojure Spec.

How can I get and have a look in it?

Eg. given

(s/def ::myspec (s/keys :opt-un [::x ::y]))

I want to pretty print the internal representation of myspec.

You can use s/form which "return[s] the spec as data":

(s/form ::myspec)
=> (clojure.spec.alpha/keys :opt-un [:user/x :user/y])

Or s/describe for an abbreviated version of the same thing:

(s/describe ::myspec)
=> (keys :opt-un [:user/x :user/y])

Both these ultimately depend on the describe* method of the Spec protocol:

(defprotocol Spec
  (conform* [spec x])
  (unform* [spec y])
  (explain* [spec path via in x])
  (gen* [spec overrides path rmap])
  (with-gen* [spec gfn])
  (describe* [spec]))

So each spec type is responsible for describing itself. For example the map spec implementation just rebuilds its literal definition from its initial inputs like this:

(describe* [_] (cons `keys
                      (cond-> []
                              req (conj :req req)
                              opt (conj :opt opt)
                              req-un (conj :req-un req-un)
                              opt-un (conj :opt-un opt-un))))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM