Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between with-redefs and with-redefs-fn in Clojure?

I would like to understand difference between with-redefs and with-redefs-fn.

Concrete examples would be great to understand the fns behaviours.

like image 710
Ertuğrul Çetin Avatar asked Apr 11 '17 14:04

Ertuğrul Çetin


2 Answers

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

like image 84
Alejandro C. Avatar answered Oct 03 '22 20:10

Alejandro C.


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.

like image 44
Alan Thompson Avatar answered Oct 03 '22 21:10

Alan Thompson