Подтвердить что ты не робот

Какой смысл определять что-то динамическое, когда вам не нужно определять что-то динамическое с помощью-redefs?

Мне кажется, что with-redefs может делать все, что binding для динамического символа может делать, только у него нет ограничений на необходимость метаданных ^:dynamic. Итак, когда я должен использовать один над другим?

4b9b3361

Ответ 1

Помимо необходимости метаданных ^:dynamic, binding также создает привязки, которые видны только в текущем потоке, тогда как привязки, сделанные with-redefs, видны во всех потоках. Таким образом, with-redefs является очень тупым инструментом и может влиять на другой код, работающий в той же виртуальной машине. Я никогда не видел with-redefs, используемого вне тестового кода, и не должен (по крайней мере, на мой взгляд).

Я бы суммировал разницу между ними так:

  • привязка с ^: динамическая позволяет вам немного управлять динамическим поведением. Это хороший способ определения точек расширения в API, которые позволяют вызывающим абонентам значительно превышать цепочку вызовов, изменяя поведение вашего кода без необходимости явно передавать параметры полностью через стек вызовов (некоторые из которых могут даже не быть их кодом).
  • с-redefs является бесплатным для всех. Это полезно при тестировании, например. для издевательства над всеми подсистемами, когда тестируемая функция имеет множество зависимостей.

Объявление var как ^:dynamic, а также соглашение об использовании наушников для обозначения динамических варов (например, *my-dynamic-var*), имеет дополнительный бонус, который является самодокументирующим способом рекламы для вызывающих абонентов, что эта часть вашего кода можно динамически изменять.

В заключение: предпочитайте ^: динамическое и привязку при написании API и производственного кода. Используйте с-redefs при тестировании и в качестве последнего средства для динамического изменения поведения vars вне вашего контроля, которые не были объявлены ^:dynamic (а затем, используйте с осторожностью).