简体   繁体   中英

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.

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.

eg

(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" (ie 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM