This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-15
Channels
- # architecture (2)
- # beginners (16)
- # boot (2)
- # cider (4)
- # clara (6)
- # cljs-dev (78)
- # cljsrn (3)
- # clojure (158)
- # clojure-austin (1)
- # clojure-belgium (1)
- # clojure-dusseldorf (19)
- # clojure-italy (8)
- # clojure-russia (3)
- # clojure-spec (77)
- # clojure-uk (61)
- # clojurescript (341)
- # cursive (9)
- # data-science (12)
- # datomic (18)
- # emacs (9)
- # fulcro (109)
- # hoplon (10)
- # juxt (2)
- # leiningen (2)
- # lumo (31)
- # off-topic (1)
- # om (4)
- # onyx (40)
- # parinfer (17)
- # re-frame (36)
- # reagent (19)
- # spacemacs (10)
- # vim (60)
- # yada (20)
For anyone that uses Orchestra to instrument :fn
and :ret
specs, Expound 0.2.0 now supports pretty error messages for Orchestra errors. https://github.com/bhb/expound#using-orchestra
Hi. I am having an issue with clojure.spec
. This code throws an error: https://gist.github.com/hmaurer/d030f9ff9250482c6dea3e3738737863
I think this is because s/keys
is a macro, but I am not sure how to get it to do what I want
@moxaj thank you! So I assume I cannot / should not define specs at runtime? e.g. I can’t define specs based on my database schema after opening a connection?
ah, I’ll try that. Is it an outright terrible idea to define specs at runtime though?
Does anyone here define specs in the same file as the functions? Above the functions like haskell type annotations
I just started to write my specs like that. Not sure if is the best practice or not.
I usually do
I lean towards: data specs in a separate file(s), function specs – next to actual implementation. (Yet to see how it'll turn out in longer run)
@U051HUZLD Right, that makes sense to. Because functions might share data specs, right?
@U489U338R yes, and, functions are more "implementation detail"-y than data, I think. But I'd start with everything in one file, and see what's up later in project.
Ya, data spec in their own namespace gives you a clean domain model. And fn specs I put below the functions.
Most of our specs are for data structures and they go in whatever is the appropriate namespace for those data structures -- which is often a separate ns but sometimes is a ns with some "utility" functions specific to the data structure. Where we spec functions we generally put the spec right above the function (like a type annotation).
But, as noted, if you want your code -- a library -- to be usable by Clojure < 1.9 then you have to put specs in a separate and completely optional namespace.
See, for example, how clojure.java.jdbc
handles this (specs in a separate namespace on their own -- even for functions).
Make clojure.spec behave more like schema in terms of keys strictness (no unknown keys allowed)
disclaimer: untested, most likely buggy
schpec has excl-keys
: https://github.com/gfredericks/schpec#things-it-has
sure, but I wanted to be able to be strict conditionally
oh sorry, I didn't look closely
Re-iterating my earlier question, does anyone have a big objection to defining specs at runtime (with eval
), based, .e.g, on the app’s database schema? I am a beginner so I am not sure if it is “good taste/practice” in the clojure world
it possible, but keep in mind, you cannot yet retract specs from registry as of now @hmaurer
so if your specs will change during application run time - make sure you migrate those appropriately
well, you can if you reach in and munge the registry atom :) but that’s coming soon.
@hmaurer I think dynamic generation of specs is fine
I am having a hard time understanding s/keys
. I keep my specs organized in separate namespaces - i.e something like entity.clj
and entity/spec.clj
. I have the following used to spec a generic entity map
I define ::id
to make importing it elsewhere easier, and then use it in ::entity/id
because its my understanding that is how the :req
field in ::entity
is able to conform that specific key?
If conceptually the id of entity is supposed to be the same as the id of todo, the you s/def :some-ns/id. And in your spec for entity you say keys req [:some-ns/id]. And do tje same in your todo spec.
Basically s/keys describes an associative structure which when used with :req says that the structure must have as keys the given list of namespaced keywords. If the keyword has a spec defined, it will be used to validate and conform the value of the key.
But if I were to define (s/def ::entity/id ...)
how can I then import that elsewhere?
or even if you use :as
- since its already namespaced in the spec - is there a way to get at it?
You don't need to refer anything, just require it.
(:require [todos.entity.spec])
Specs are always defined globally. All that needs to happen is your app must eval the s/def form before you use it. Require will do that.
So specs are namespaced. They're globally accessible from anywhere after they've been deffed, but they need to be prefixed with a namespace. This helps reduce name clash.
So if you are in namespace todos.entity.spec and you s/def a spec, and you use the double colon ::, then you created :todos.entity.spec/your-spec
Now if you are in say todos.app namespace, you can require todos.entity.spec and refer to the spec as :todos.entity.spec/your-spec
Either define the spec like that, so don't use the double colon, you can (s/def :entity/id int?)
for example
This will be make it less portable though, since the chance of name clash are higher.
Or you can define it prefixed with the full namespace using ::, and then when you use it elsewhere, you can alias the namespace as entity.
`(ns ns1) (s/def ::id int?)` Then in ns2 `(ns ns2 (:require [ns1 :as entity]) (s/def ::user :entity/id)`
As far as I know, you can't refer a spec yet. But you can kinda manually do it if you want
So I have a cat
spec that contains a UUID for one field, and another field is a coll-of maps, and each map has a :guid->UUID; the requirement is that one of the maps contain the UUID. I can express this in a spec, but I’m not sure how to make a generator for such a scenario
is this useful? https://github.com/lbradstreet/cljs-uuid-utils
Ya, data spec in their own namespace gives you a clean domain model. And fn specs I put below the functions.
clojure.spec.gen.alpha/uuid
is sufficient for generating UUIDs, the problem is ensuring the first UUID appears in the second collection
(gen/let [recs (gen/not-empty recs) special-uuid (gen/elements (map :guid recs))] [recs special-uuid])
Hi. Is there a straightforward way to serialize the result of explain-data
to JSON? I am getting an error on trying to serialize spec predicate functions
@U2J4FRT2T it looks like it cannot encode functions (`:pred` key in the spec problems)
@U0K064KQV I am consuming it from a JS frontend so EDN does not seem ideal
@U051HUZLD not much, I just want a string so I can know why validation failed for a specific field
Or just use s/explain-str
instead of s/explain-data
Or would that be too opaque? 🙂
@U06GVE6NR too opaque; I need to know which fields contain errors 🙂
@U051HUZLD I didn’t know the function pr-str
; thank you!