Мне кажется, что with-redefs
может делать все, что binding
для динамического символа может делать, только у него нет ограничений на необходимость метаданных ^:dynamic
. Итак, когда я должен использовать один над другим?
Какой смысл определять что-то динамическое, когда вам не нужно определять что-то динамическое с помощью-redefs?
Ответ 1
Помимо необходимости метаданных ^:dynamic
, binding
также создает привязки, которые видны только в текущем потоке, тогда как привязки, сделанные with-redefs
, видны во всех потоках. Таким образом, with-redefs
является очень тупым инструментом и может влиять на другой код, работающий в той же виртуальной машине. Я никогда не видел with-redefs
, используемого вне тестового кода, и не должен (по крайней мере, на мой взгляд).
Я бы суммировал разницу между ними так:
- привязка с ^: динамическая позволяет вам немного управлять динамическим поведением. Это хороший способ определения точек расширения в API, которые позволяют вызывающим абонентам значительно превышать цепочку вызовов, изменяя поведение вашего кода без необходимости явно передавать параметры полностью через стек вызовов (некоторые из которых могут даже не быть их кодом).
- с-redefs является бесплатным для всех. Это полезно при тестировании, например. для издевательства над всеми подсистемами, когда тестируемая функция имеет множество зависимостей.
Объявление var как ^:dynamic
, а также соглашение об использовании наушников для обозначения динамических варов (например, *my-dynamic-var*
), имеет дополнительный бонус, который является самодокументирующим способом рекламы для вызывающих абонентов, что эта часть вашего кода можно динамически изменять.
В заключение: предпочитайте ^: динамическое и привязку при написании API и производственного кода. Используйте с-redefs при тестировании и в качестве последнего средства для динамического изменения поведения vars вне вашего контроля, которые не были объявлены ^:dynamic
(а затем, используйте с осторожностью).