hi
hi!
@borkdude I haven’t had a use case for a transform function before, so I’m a hesitant to add a callback w/o understanding the use case more
I’m curious about why transforming the value is better than changing the printer
the use case is printing only a part of the data, not all
because I’m happy with how things are printed, it’s just too much
the issue is the map is too large, even when most of it is omitted?
(i.e. printed with ...
placeholders)
does it do that now?
I’ll test
It should do that now e.g. https://github.com/bhb/expound#expound-1
(the example with city/state)
it’s entirely possible that the specific spec+data is not working w/ this feature, which would be good to know
I still get a couple of tens of lines from my map that isn’t that relevant
(being the system map from component)
ah, this is failing on a keys
spec, is that correct?
yup
gotcha, yeah, I’ll file an issue but it’s possible to print the summary map in that case
I’ll think about it more
I’m not sure a transform function would be a general solution though - what’s the strategy for picking which part of the map to remove?
It seems like it’d be hard to write a general transformer that doesn’t leave out necessary data in some cases
the strategy is up to the user in the same way the the string function is up to the user
but if you could explain me how to do the summary thing, that might work for me
Sorry, I was unclear - what’s the strategy in your case? If a map is a component map, which keys would you remove?
in my case the strategy would be to just print the keys
Oh sorry, I misspoke: ” it’s possible to print the summary map in that case” - I meant it’s possible expound could do this
🙂
If you want to print the keys, would the custom printer work? I guess I’m wondering how you’d use the transform
function in this case
(as I do now in the custom printing function, but I lose expound’s nice ability to highlight stuff etc)
I would do :transform keys
or no
(if (map? v) (keys v) v)
Ah, I think that’s going to get confusing though - now the data that is shown to fail is not the same thing
as what you actually entered
so, for instance, the highlighter is going to look really weird
but maybe that’s OK in your use case 🙂
ah, I understand. so falling back on the default printing function is the easier way out then
if it were easily accessible 🙂
In any case, I think you can try this out today, although with some work, because you can modify the explain-data
if you wanted
my custom string function now looks like this:
(defn my-value-str [_spec-name form path value]
(if (and (map? value)
(every? (fn [ns]
(when ns
(str/starts-with? ns "<http://dre.app|dre.app>")))
(map namespace (keys value))))
(str (keys value))
(str value)))
e.g.
(set! s/*explain-out*
(fn [explain-data]
(let [new-explain-data (replace-map-with-keys explain-data)]
((expound/custom-printer {,,,}) new-explain-data)))
(untested, and granted it’s not very pretty)
interesting
you should be able to do something like this (untested)
(def default-value-str #'expound/value-in-context)
(defn my-value-str [_spec-name form path value]
(if (and (map? value)
(every? (fn [ns]
(when ns
(str/starts-with? ns "<http://dre.app|dre.app>")))
(map namespace (keys value))))
(str (keys value))
(default-value-str my-printer-opts spec-name form path value)))
untested, and also not super pretty 😞
k, I’ll play a little with this, thanks 🙂
sounds good, I think the second one is probably going to be less work overall, but I could be mistaken
in any case, I agree with you that this is painful, I’ll think more about how to best allow users to control this while allowing them to fallback in a sensible way
This worked:
(declare my-expound-value-str)
(def expound-opts
{:show-valid-values? false
:value-str-fn #'my-expound-value-str
:print-specs? true})
(defn my-expound-value-str
[_spec-name form path value]
(if (and (map? value)
(every? (fn [ns]
(when ns
(str/starts-with? ns "<http://dre.app|dre.app>")))
(map (fn [k]
(and (keyword? k)
(namespace k)))
(keys value))))
(str (keys value))
(#'expound/value-in-context expound-opts _spec-name form path value)))
(defn my-explain-out
[explain-data]
((expound/custom-printer
expound-opts) explain-data))
(defn activate-specs
"Check spec asserts and fdefs"
[]
(alter-var-root #'s/*explain-out*
(constantly #'my-explain-out))
(s/check-asserts true)
(st/instrument))
Nice work! 💯
It’s mostly your work, so thank you 🙂
Can you remove my-explain-out
and just incline the custom-printer
in this case?
yeah I can, but it gives options 😉
good point 😉
you were right that editing explain-data was a bit more work, so I didn’t do it now. I could walk the tree
I guess I could do the same with the thrown exception
the trick with the thrown exception is that it has already used expound to create the string, so you’d have to do string replacement, which might be unreliable
yes, I would walk both trees. so explain-data before it gets to expound and the one packaged in the ex-info
ah, right
yeah, could do. in principle you can modify explain-data
but you may run into weird expound errors if the explain-data isn’t consistent. I haven’t tried it though
ah right
expound doesn’t do anything to protect itself against invalid explain-data. in principle, it could use a spec for explain-data, but I haven’t gotten around to writing one, since it’s not easy 🙂
meh, I think it’s good now. thanks a lot
np, thanks for the helpful questions and feedback!