clojure - Difference between using "def" to update a var and "alter-var-root" -
what's difference between using "def" update var , using "alter-var-root"? e.g.
(def x 3) (def x (inc x))
vs
(def x 3) (alter-var-root #'x inc)
i find alter-var-root comes in idiomatic clojure code; not there wrong it, it's intended corner cases. if find using build loops , such it's sign needs different approach. see in initialization routines setting access credentials or loggers , such.
alter-var-root
uses function mechanically change value of var while def
sets new value. in example equivalent.
hello.exp> (def foo 4) #'hello.exp/foo hello.exp> (alter-var-root #'foo inc) 5 hello.exp> foo 5
alter-var-root
unwilling create new var:
hello.exp> (alter-var-root #'foo1 inc) compilerexception java.lang.runtimeexception: unable resolve var: foo1 in context, compiling:(no_source_path:1)
alter-var-root
can work on other namespaces well:
hello.exp> (in-ns 'user) #<namespace user> user> (alter-var-root #'hello.exp/foo inc) 6 user> (def hello.exp/foo 4) compilerexception java.lang.runtimeexception: can't create defs outside of current ns, compiling:(no_source_path:1) user>
this last use case 1 have ever needed in practice. instance forcing clojure.logging
use correct slf4j logger example pallet project:
(defn force-slf4j "the repl task brings in commons-logging, messes our logging configuration. attempt restore sanity." [] (binding [*ns* (the-ns 'clojure.tools.logging.slf4j)] (alter-var-root #'clojure.tools.logging/*logger-factory* (constantly (clojure.tools.logging.slf4j/load-factory)))))
which using alter-var-root
reset var in namespace regardless of content on initialization. suppose it's bit of hack ...
Comments
Post a Comment