Let's say we need evaluate a number of clauses in a source file, e.g.
test.clj
@(def x 1)
@(def y 2)
@(def z 3)
Only the last evaluation shows up if we plainly use either clj
or lein repl
,
user => (load-file "test.clj")
3
We can surround each of them by println
to show all of them,
test-with-println.clj
(println @(def x 1))
(println @(def y 2))
(println @(def z 3))
user => (load-file "test-with-println.clj")
1
2
3
nil
What are the better alternatives to avoid invasive println
s all over the source code while able to print out all the intended evaluations under the umbrella of REPLs?
@Solution
Thanks to tap>
from the answer @Sean Corfield we can have desired results as follows,
tap>
.test-with-tap.clj
(-> @(def x 1) tap>)
(-> @(def y 2) tap>)
(-> @(def z 3) tap>)
tap>
is turned on by add-tap
.user=> (load-file "test-with-tap.clj")
nil
user=> (add-tap @(def out (bound-fn* println)))
nil
user=> (load-file "test-with-tap.clj")
1
2
3
user=> (remove-tap out)
nil
user=> (load-file "test-with-tap.clj")
nil
tap>
is probably what you're looking for - https://clojuredocs.org/clojure.core/tap%3E - This lets you send full Clojure values (not just strings) to any function registered as a listener, which can be something like Portal for example - https://github.com/djblue/portal - which is something I use all-day, every-day, but you can also use something as simple as println
in add-tap
to get every tap>
'd value displayed.
The tap>
calls can stay in your code, even in production, since there is next to no overhead to using them.
Although tap>
returns a Boolean, you can use (doto expr tap>)
to evaluate and return expr
but still send the value to any tap listeners. tap>
is a great debugging tool.