I know that you have to call stest/instrument
again when you change the function definition because instrument
wraps the original function and replaces the var root - when you redefine the fn, it's no longer instrumented.
But I thought that just changing the fdef
definition would be fine (no need to call instrument
again) because the spec is hold in global registry. But any change inside fdef
still requires calling instrument
again - is this because the spec fn wrapper captures the fdef spec value as it was at the instrument
was called?
After looking at spec code, I think the "problem" is that it doesn't call get-spec
at the time the function is invoked but rather at the time when instrument
is called and thus it only captures the spec as it was at that time - no later redefinitions are taken into account.
yep, exactly - this is a performance optimization
typical tradeoff of perf vs dynamicity :)
@jumar What I tend to do in situations like that is put the stest/instrument
call in my test namespace as a top-level form (after ns
but before any tests) so that the tests run with up-to-date instrumentation. If you want to do it in a source file, you could always have something like
(comment
(do
(stest/instrument `my-fn)
(my-fn 123)) ; eval this form with both the instrument call and the my-fn call
,)
@seancorfield Would love to see a youtube video about the spec dimension of your development workflow, if you ever feel like it. I remember enjoying the demonstration of your REBL workflow
@uwo Noted. I'm not sure when I'll get back to making videos -- I really hate the process (and the medium): I much prefer prose and code to videos.
I also have a couple of helper macros here for in/unstrumentation: https://github.com/borkdude/respeced#with-instrumentation https://github.com/borkdude/respeced#with-unstrumentation They ensure the desired state in the body, but will restore the state like it was afterwards