Fork me on GitHub
#clojure-spec
<
2018-06-30
>
kurt-o-sys13:06:39

if I have a map:

(def m #::{:item1 #::{:name         "whatever"
                      :description  "..."
                      :ref []}
           :item2 #::{:name "another one"
                      :description "...?"
                      :ref [:item1]})
can I write a spec so that all items in ::ref are keys of the containing map?
(s/def ::ref (coll-of ...??...))
or
(s/def ::ref (key-set ...??...))

ackerleytng15:06:31

i think you can spec it as a predicate

ackerleytng15:06:45

let me try it out on my side first

ackerleytng15:06:41

something like that

(def m1 {:a {:b 1
             :ref [:a]}})

(def m2 {:a {:b 1
             :ref [:c]}})

(defn ref-contains-keys-of-containing-map [m]
  (let [ks (keys m)]
    (= (:ref (first (vals m))) ks)))

(s/def ::m (s/and map?
                  ref-contains-keys-of-containing-map))

(s/conform ::m m1)
(s/conform ::m m2)

ackerleytng15:06:03

m1 conforms, m2 doesn't

kurt-o-sys16:06:02

right, thx... will try.

kurt-o-sys16:06:43

oh right, but will see if I can make that more dynamic in some way... I'm fetching the map from outside. well... will see 😛

kurt-o-sys16:06:57

@clojurians.net I like ghostweel - just trying it now - but it doesn't validate the return value of >defn. I seem to remember clojure.spec itself doesn't either, but orchestra does so... Any plans to add this to ghostweel as well (validation of return values of functions)?

justinlee16:06:32

@kurt-o-sys have you configured to do so? there’s a separate config option to turn that on

andre.stylianos17:06:18

;; Spec-instrument functions on namespace reload.
 ::instrument      false

 ;; Spec-instrument functions on namespace reload using orchestra,
 ;; which spec-checks the output in addition to the input.
 ::outstrument     false

kurt-o-sys18:07:38

I didn't... - I didn't know it was an option, but I do now 🙂.

andre.stylianos19:07:50

😜 Glad to help!

gnl18:06:08

@kurt-o-sys It's already in there! The option is ::g/outstrument.

gnl18:06:03

Didn't read the other replies before I answered. By the way there's a bug in the current stable version, where ::g/instrument and ::g/outstrument require ::g/check to be enabled to have any effect. This doesn't really make any sense and is fixed in 0.2.2-SNAPSHOT, soon to be released as a stable 0.2.2 once some Figwheel issues have been cleared up.

kurt-o-sys18:07:15

nice, thx! I did figure it out concerning that ::g/check issue, not about the ::g/oustrument 😛. Thanks a lot. Just one more question: how would you recommend instrumenting only during dev, but not for a prod build? (Just wondering what you consider as best practice)

kurt-o-sys18:07:36

also, I must be doing something wrong:

(>defn target
       "target function to be minified"
       {::g/instrument  true
        ::g/outstrument true}
       [in]
       [any? => double?]
       "wrong")
This should fail, right? (return value should be of type double, but it's a string). However, it doesn't fail at all. Adding the config to the ns doesn't help either:
(ns test-gw.core
  #:ghostwheel.core{:instrument  true
                    :outstrument true}
  (:require [clojure.spec.alpha :as s]
            [ghostwheel.core :as g
             :refer [>defn >defn- >fdef ? => | <-]])
 ...)

gnl18:07:44

Don't use ::g/instrument and ::g/outstrument together, only one will be used, in this case ::g/instrument. What you want here is only ::g/outstrument.

gnl18:07:47

And regarding not instrumenting in production – just make sure that ghostwheel isn't enabled in your prod build config

gnl18:07:51

No way to do that in Clojure at the moment, so just don't do instrumentation there in production. 🙂

kurt-o-sys18:07:29

right, perfect 👍 👍