This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-28
Channels
- # babashka (48)
- # babashka-sci-dev (7)
- # beginners (123)
- # calva (32)
- # cider (5)
- # clara (20)
- # clj-kondo (3)
- # cljdoc (2)
- # cljs-dev (1)
- # clojure (113)
- # clojure-dev (5)
- # clojure-europe (65)
- # clojure-norway (23)
- # clojure-spec (4)
- # clojure-uk (4)
- # clojurescript (33)
- # cursive (3)
- # datalevin (39)
- # datomic (2)
- # emacs (14)
- # events (1)
- # fulcro (10)
- # graphql (5)
- # humbleui (2)
- # integrant (4)
- # introduce-yourself (3)
- # jobs (1)
- # jobs-discuss (11)
- # kaocha (26)
- # leiningen (6)
- # malli (24)
- # nbb (2)
- # off-topic (69)
- # pathom (77)
- # podcasts-discuss (2)
- # reitit (8)
- # remote-jobs (2)
- # sci (17)
- # scittle (8)
- # squint (1)
- # xtdb (43)
What does this error mean? https://github.com/metosin/malli/blob/c0965e2b2b37ea1d81e6f4ece7c87f56fa90398a/test/malli/core_test.cljc#L1799 I get it when I try to have a malli schema to decode malli tuples. And well... it has to be recursive :thinking_face:
I fixed the error by not using :ref
in the definition like this:
::malli-tuple-schema [:cat
[:= :tuple]
[:* ::malli-schema]
#_[:* [:ref ::malli-schema]]]
I think it means that any regex operation cannot contain a recursive schema. checking for :ref
is a crude way of checking for recursion.
I developed a more refined way to detect recursive specs in the generators namespace. perhaps using that here would be a nice enhancement.
> cannot contain a recursive schema
Well if I remove the :ref
it will still reference the ::malli-schema
but it will copy it. So the schema works the same way as it would work with :ref
eg., the ;; A bit undesirable, but intentional:
test a few lines down from the test you linked.
Everything there is recursive 😄
::malli-schema [:or
[:ref ::malli-map-schema]
[:ref ::malli-set-schema]
[:ref ::malli-vector-schema]
[:ref ::malli-tuple-schema]
:keyword]
This looks like [:* ::malli-schema]
and it works without the error
I thought it was an overapproximation on checking for recursive specs. but it only guards against very specific recursive ones.
This is a more basic example that passes the checker:
[:schema
{:registry
{::malli-field-options [:map
[:optional {:optional true} :boolean]
[:min {:optional true} :int]
[:registry {:optional true} ::malli-map-schema]],
::malli-map-schema [:cat
[:= :map]
[:* [:or
[:tuple :keyword [:ref ::malli-schema]]
[:tuple :keyword [:ref ::malli-field-options] [:ref ::malli-schema]]]]],
::malli-schema [:or
[:ref ::malli-map-schema]
:keyword]}}
::malli-schema]
ok, and that one has no references/`:ref` directly on regex ops. can you post the full one that yields the error and requires a change?
I don't know. I can't find it
I'll probably be editing it more. Maybe I can find it later. But when I got that bug I was unsure what to do. So it's a tough one.
the :ref
can’t be used to expand/inline things into a sequential schema. you can use :ref
s, but need to wrap it into :schema
- takes just one position in the sequence. This is an implementation decision, described in the ns. If there is a performant way not to do this, I’m all 👂s!
Got a question about malli’s :re
schemas.
I’ve got this code for validating email addresses:
(def email-address-regex #"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])")
(def email-address? [:re {:error/message "Please provide a valid email address"} email-address-regex])
(me/humanize (m/explain email-address? ",bad-email")) ;; will say it's valid
(re-matches email-address-regex ",bad-email") ;; will not match anything
It seems like :re
is using re-find
because re-find
does return true, but what can I do to make :re
behave more like re-match
?Yeah, it seems it's using re-find
for validation: https://github.com/metosin/malli/blob/0.8.9/src/malli/core.cljc#L1350-L1351
In that case, you need to use the "beginning of line/string" (`^`) and "end of line/string" (`$`) anchors in your regular expression, so that re-find
must match your regular expression over the whole input value, not just a part of it:
user> (require '[malli.core :as m])
nil
user> (require '[malli.error :as me])
nil
user> (def email-address-regex #"^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:\
(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$")
#'user/email-address-regex
user> (def email-address? [:re {:error/message "Please provide a valid email address"} email-address-regex])
#'user/email-address?
user> (me/humanize (m/explain email-address? ",bad-email")) ;; will say it's invalid
["Please provide a valid email address"]
user> (re-matches email-address-regex ",bad-email") ;; will not match anything
nil
user> (re-find email-address-regex ",bad-email") ;; will not match anything either
nil
user>
Thanks!