clojure.core има макросите свързвания и с-redefs. Разглеждайки документационните низове и примерите на clojuredocs.org, те изглежда правят нещо много подобно. Каква е разликата и кой трябва да използвам в какви ситуации?
Clojure: обвързване срещу with-redefs
comment
Вижте също този въпрос: stackoverflow.com/questions/15747774/
- person Alex   schedule 22.11.2013
Отговори (1)
Clojure Vars може да има локално обвързване на нишка. binding
ги използва, докато with-redefs
всъщност променя основното свързване (което е нещо като стойността по подразбиране) на променливата.
Друга разлика е, че binding
работи само за :dynamic
променливи, докато with-redefs
работи за всички променливи.
Примери:
user=> (def ^:dynamic *a* 1)
#'user/*a*
user=> (binding [*a* 2] *a*)
2
user=> (with-redefs [*a* 2] *a*)
2
user=> (binding [*a* 2] (doto (Thread. (fn [] (println "*a* is " *a*))) (.start) (.join)))
*a* is 1
#<Thread Thread[Thread-2,5,]>
user=> (with-redefs [*a* 2] (doto (Thread. (fn [] (println "*a* is " *a*))) (.start) (.join)))
*a* is 2
#<Thread Thread[Thread-3,5,]>
Можете да използвате (недокументирания) binding-conveyor-fn
, за да прехвърлите локални за нишки обвързвания в нови нишки:
user=> (binding [*a* 2] (doto (Thread. (#'clojure.core/binding-conveyor-fn (fn [] (println "*a* is " *a*)))) (.start) (.join)))
*a* is 2
#<Thread Thread[Thread-5,5,]>
person
opqdonut
schedule
22.11.2013
Всичко това е причината
with-redefs
да е предназначен за използване в тестове (където може да искате да достигнете и да изтриете функция), което binding
може да бъде полезно и в производствен код.
- person Peeja; 29.09.2014
@Peeja благодаря, с други думи,
with-redefs
никога не трябва да се използва в многонишков контекст?
- person Erik Kaplun; 11.06.2019
@opqdonut от юни 2019 г. документацията на Vars има раздел Обвързващо предаване, който подчертава
future
, send
, send-off
и pmap
като притежаващи възможностите за обвързване на пренос — означава ли, че binding-conveyor-fn
вече не е необходим?
- person Erik Kaplun; 11.06.2019
@ErikKaplun,
binding-conveyor-fn
не е необходим, ако използвате функциите, които споменахте. Въпреки това, ако създавате нишки с (Thread. ...)
, все още имате нужда от него.
- person Miikka; 14.01.2020