Fork me on GitHub
#cider
<
2022-11-18
>
pavlosmelissinos10:11:29

;; ns x
(def foo "something")

;;ns y
(def foo x/foo)

;;ns z
(println y/foo)
Changing the value of x/foo to "something else" requires reevaluating y/foo otherwise ns z doesn't pick up the change. This was a bit unintuitive but I suppose it is expected because vars != refs (?)... I get the same behaviour when x/foo is a function. Is there a cider function that will reload all of the nses in between automatically? cider-load-buffer and cider-ns-refresh don't work.

Rupert (All Street)11:11:31

If you use integrant -then you can use a library called https://github.com/weavejester/integrant-repl - that will detect all files that have changed and reload them correctly according to their dependency graph. I have it set to a hotkey in emacs.

👍 1
pavlosmelissinos11:11:18

Thanks, I'll check it out! I thought cider-ns-refresh was supposed to do that as well (both use clojure.tools.namespace under the hood) I'm starting to suspect there's something wrong with my setup :thinking_face:

👍 1
pithyless15:11:04

This is why sometimes you'll see things like:

(ns x)
(defn foo [] "something")

(ns y)
(def foo #'x/foo)

(ns z)
(y/foo)
Now, if you change x/foo, you will always get the newest value, since y/foo is a reference to the var and not a specific implementation. BTW: This works kind of by magic, because Clojure will silently deref vars if you treat them as function calls. If foo was a def not a defn in namespace z you would need to first deref: @y/foo

👌 1
pithyless15:11:53

I think a good example of this in practice is in the reitit docs, where it shows how to differentiate between a dev router (recompiling on request/save/whatever) and a production router (compiled and memoized). https://cljdoc.org/d/metosin/reitit/0.5.18/doc/advanced/dev-workflow?q=dev#an-easy-fix

pithyless15:11:15

Notice in particular, that if you think through the cases where this kind of behavior may be beneficial (dev vs prod, dynamic vs static) - you can architect a REPL-friendly system without having to rely on specific tooling (like integrant-repl or clojure.tools.namespace.refresh).

pavlosmelissinos16:11:51

> you can architect a REPL-friendly system without having to rely on specific tooling (like integrant-repl or clojure.tools.namespace.refresh). Indeed! To be honest I'd rather not use either 🙂

ghadi21:11:36

how can I control the default print output of byte arrays?

dpsutton21:11:26

try

(def ^:dynamic *pretty-objects*
  "If true, cider prettifies some object descriptions.
  For instance, instead of printing functions as
      #object[clojure.core$_PLUS_ 0x4e648e99 \"clojure.core$_PLUS_@4e648e99\"]
  they are printed as
      #function[clojure.core/+]

  To disable this feature, do
      (alter-var-root #'cider.nrepl.print-method/*pretty-objects* not)"
  true)

dpsutton21:11:40

i’m not 100% sure this is the cause but a good first attempt

dpsutton21:11:45

i think this is the default pretty printer?

(clojure.pprint/pprint (.getBytes "foo"))
[102, 111, 111]

ghadi21:11:57

pprint is doing this!?

dpsutton21:11:22

❯ clj
Clojure 1.11.1
user=> (require '[clojure.core.server :as server]
         '[clojure.string :as str]
         'clojure.test
         'clojure.pprint)
nil
user=> (clojure.main/repl
 :prompt (fn [] (printf "%s=> " (peek (str/split (str *ns*) #"\."))))
 :eval (fn [f] (binding [clojure.test/*test-out* *out*] (eval f)))
 :read server/repl-read
 :print clojure.pprint/pprint)
user=> (.getBytes "foo")
[102, 111, 111]
user=> :repl/quit
nil
user=> (.getBytes "foo")
#object["[B" 0x3bb8aabc "[B@3bb8aabc"]

dpsutton21:11:35

switch the pretty printer to fipp and it’ll be what you expect

ghadi21:11:04

great, thanks @U11BV7MTK!

👍 1
ghadi21:11:57

they are showing up as if by (seq byte-array)

[-8, -64, 77, 61, 79, 96, 76, -112, -93, 67, -57, -7, 76, 124, 30, 121]