I would like to understand difference between with-redefs
and with-redefs-fn
.
Concrete examples would be great to understand the fns behaviours.
They're basically the same, the main difference is that with-redefs
lets you write out the body explicitly (like in a let
), while with-redefs-fn
requires a function as the argument, so you may need to wrap what you want in a lambda. Additionally, with-redefs
lets you provide bindings using a vector (again, like let
), while with-redefs-fn
wants a map. I'd argue that both of these differences are just superficial.
e.g.
(with-redefs [http/post (fn [url] {:body "Goodbye world"})]
(is (= {:body "Goodbye world"} (http/post "http://service.com/greet"))))
vs
(with-redefs-fn {#'http/post (fn [url] {:body "Goodbye world"})}
(fn [] (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))
In fact, with-redefs
is defined in terms of with-redefs-fn
, and basically just wraps the body in an anonymous function before passing everything to with-redefs-fn
: https://github.com/clojure/clojure/blob/e3c4d2e8c7538cfda40accd5c410a584495cb357/src/clj/clojure/core.clj#L7404
I would ignore with-redefs-fn
and use only with-redefs
since it is simpler and has the same abilities. Also, beware that the notation #'http/post
requires you to use the var for http/post
, not the function itself.
For a description of how a Clojure var
works, please see this question: When to use a Var instead of a function? It is similar to a C pointer.
In clojure, when you see foo
, it is a symbol. When you see #'foo
, it is a shortcut for (var foo)
which is a "special form" (i.e. a Clojure built-in, not a regular function), which returns the var
that foo
points to. The var
in turn points the the value of foo
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With