So, maybe we could change variable metadata to make the variable dynamic. Unfortunately, changing metadata using alter-meta! doesn't trigger its re-evaluation. Consider the following:
user=> (def x 42)
#'user/x
user=> (alter-meta! #'x assoc :dynamic true)
{:ns #, :name x, :dynamic true, :line 1, :file "NO_SOURCE_PATH"}
user=> (.isDynamic #'x)
false
false
user=> (binding [x 32] (println x))
IllegalStateException Can't dynamically bind non-dynamic var: user/x clojure.lang.Var.pushThreadBindings (Var.java:353)
Instead we can call .setDynamic directly:
user=> (.setDynamic #'x)
#'user/x
user=> (binding [x 32] (println x))
32
nil
If you want to redefine variables temporarily, without making them dynamic (e.g., for mocking out functions during testing), you can use new functions that were added to cover such use case - with-redefs-fn and with-redefs.
IllegalStateException Can't dynamically bind non-dynamic var: user/x clojure.lang.Var.pushThreadBindings (Var.java:353)
Instead we can call .setDynamic directly:
user=> (.setDynamic #'x)
#'user/x
user=> (binding [x 32] (println x))
32
nil
If you want to redefine variables temporarily, without making them dynamic (e.g., for mocking out functions during testing), you can use new functions that were added to cover such use case - with-redefs-fn and with-redefs.