захват переменной с макросом в clojure - PullRequest
1 голос
/ 07 мая 2019

Я пытаюсь использовать эту технику для привязки значения к переданному символу в макросе.

(defmacro t2macro [all-bindings body] (reduce (fn [acc [v binding]]
                                                 `(let [~v ~binding] ~acc))
                                                   `(do ~@body) all-bindings))
#'plans-client.mock/t2macro
plans-client.mock> (t2macro [[a 1] [b 2]] (print (+ a b)))
3

Эта упрощенная версия отлично работает.Теперь, когда я пытаюсь использовать ту же технику в контексте моего списка макросов, это

(defmacro with-mocked-grpc
  [mocked-responses & body]
  (let [mocks (for [[mock-name [status response]] (partition-all 2 mocked-responses)]
                (let [conformed-resp
                      (specs-util/conform-or-throw ::response response)
                      generated-resp (check-response conformed-resp mock-name)
                      bindings       (check-bindings generated-resp)]
                  (with-meta [mock-name [status generated-resp]]
                    (when bindings {:bindings bindings}))))
        all-bindings (map (fn [m] (:bindings (meta m))) mocks)]
    (reduce (fn [acc [v binding]]
              `(let [~v ~binding] ~acc))
            `(do ~@body) all-bindings)))

И я называю это так

(with-mocked-grpc [plans/usage-summary [:ok ^{:sized 100 :binding a} _]] 1)

Я получаю это исключение

CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(*cider-repl plans-service/client:localhost:45691(clj)*:204:20)

check-response создает сгенерированное значение для потребителя этого макроса для использования в тесте, check-binding находит сгенерированные значения, которые пользователь попросил связать с переменной.

macroexpand возвращает

(let [a {:generated :value}] 1) 

1 Ответ

1 голос
/ 07 мая 2019

Метаданные по-прежнему разрешаются после расширения макроса, поэтому изменив строку let на

(let [~(with-meta v nil) ~(with-meta binding nil)] ~acc)

Исправлено.

...