Unable to change / set root binding: [some-def] with installation in Clojure

I could not set the new value of dynamic var.

(def *pop* true)

(set! *pop* false)

=> IllegalStateException Can't change/establish root binding of: *pop* with set  clojure.lang.Var.set (Var.java:221)


I also added ^:dynamicthat didn't work either.

(def ^:dynamic *pop* true)

(set! *pop* false)

=> IllegalStateException Can't change/establish root binding of: *pop* with set  clojure.lang.Var.set (Var.java:221)


But then again, this code works, (clojure core var → *warn-on-reflection*)

(set! *warn-on-reflection* true)
=> true

*warn-on-reflection*
=> true

(set! *warn-on-reflection* false)
=> false

*warn-on-reflection*
=> false
+4
source share
2 answers

Dynamic vars can be set!inside an area binding. So just calling set!in *pop*will not work - you need to be in the dynamic execution area to bind somewhere in the call stack above.

(def ^:dynamic *pop* true)
(binding [*pop* *pop*]  ;; defaulted to the root binding value
  (set! *pop* false)    ;; ok, because in dynamic binding scope
  (println *pop*))      ;; prints "false" (inside per-thread dynamic binding)
(println *pop*)         ;; prints "true" (root value)

, " " , binding - *pop*.

*warn-on-reflection*, , , . REPL eval REPL vars, *warn-on-reflection* . .

+5

alter-var-root .

user=> (def *pop* true)
Warning: *pop* not declared dynamic ...
#'user/*pop*

user=> (alter-var-root #'*pop* (constantly false))
false

user=> *pop*
false
+2

Source: https://habr.com/ru/post/1669533/


All Articles