This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-26
Channels
- # bangalore-clj (3)
- # beginners (47)
- # boot (20)
- # cljs-dev (7)
- # cljsjs (16)
- # cljsrn (3)
- # clojure (46)
- # clojure-art (4)
- # clojure-berlin (1)
- # clojure-brasil (2)
- # clojure-greece (1)
- # clojure-india (5)
- # clojure-russia (1)
- # clojure-spec (34)
- # clojure-taiwan (2)
- # clojure-uk (8)
- # clojurescript (69)
- # cursive (9)
- # datascript (26)
- # datomic (1)
- # emacs (2)
- # events (1)
- # hoplon (8)
- # leiningen (3)
- # off-topic (4)
- # proto-repl (4)
- # re-frame (3)
- # reagent (1)
- # rethinkdb (8)
- # rum (3)
- # vim (83)
Is there a way to specify that I expect the value of a var to be valid according to a particular spec, such that it is automatically tested?
Sometimes they’re just data structures, but they might also be the result of a higher order function
@lvh map-of
does take specs...?
(s/map-of ::foo ::bar)
works...
@lvh you could just check s/valid?
when you set the var. You can use set-validator!
on vars but I’m assuming you’re not actually changing it after you set it.
Is it possible to inspect a spec to get, e.g., the list of keys defined by (s/keys :req [a b c])? I’ve created a spec for a map and want to retrieve the list of keys expected for that map for a purpose other than checking the spec.
@kestrel7 clojure.spec/form
is what you're looking for
Perhaps a noob question but from that how do I extract the actual list of keys from the resulting structure, which in this case looks like the following example but could I guess be more complex? Naively I could just say (last (s/form the-spec)) but that’s not going to be robust if the form contents change. (clojure.spec/keys :req [:k.specs.person/title :k.specs.person/first-name :k.specs.person/other-names :k.specs.person/last-name])
That's the tricky bit, hehe
I guess I could use core.match somehow. It would be useful to get the spec as data that’s easier to interrogate. Thanks for the help @dergutemoritz
You can do something like that for the simple case of a single s/keys
spec. However, when stuff like s/merge
is involved, it gets a lot trickier
It would be useful to have specs for those forms so you could s/conform
them.
For the moment I’m going to cheat: (def the-keys [::a ::b ::c] (s/def ::m (s/keys :req the-keys)
I'm not sure if anyone has put effort into defining such specs already. I was gonna take a stab at that myself when I find some time
@kestrel7 That cheat won't work I'm afraid
The keys vector needs to be literal IIRC
Because it's processed at macro expansion time
Right, just try it in the REPL and you'll see
@dergutemoritz you’re right 😞
@kestrel7 (apply hash-map (rest (s/form your-keys-spec)))
should give you a reasonable data structure to work with for bare s/keys
specs
@dergutemoritz I’ll try that.
(defn spec-keys "Return the :req keys from the spec" [spec] (let [spec-form (s/form spec)] (assert (= 'clojure.spec/keys (first spec-form))) (:req (apply hash-map (rest spec-form)))))
Should do the trick
You could destructure spec-form
right there in the let
but I guess that's just cosmetics 🙂
@seancorfield huh! I knew that compiled but I assumed it was treating the keyword as a predicate
Is there a way to unwrap a regex op context that was previously created with s/spec
?
Hmm regex-spec-impl
doesn't look like it offers something like that
I have specs for all the forms and those will be published, but I'm still working through fixing all the bugs in form first
With those, you will be able to conform any spec form to get at its parts
Ah heck 🙂 throws his Saturday afternoon hack into the trash bin
Well, I'll keep it around, perhaps I came up with some things that could be added to your implementation