Когда вы вызываете макрос with-cache-listener-m
, аргумент body
ограничивается символом 'm-callbacks
, поэтому при попытке деструктурировать этот локальный var он не будет работать, потому что это не карта.Вы можете позволить полученной форме выполнять работу следующим образом:
(defmacro with-cache-listener-m [component event body]
`(let [{:keys [f-insert# f-update#]} ~body]
(. ~component addMapListener
(proxy [AbstractMapListener] []
(entryInserted [~event] f-insert# ~event)
(entryUpdated [~event] f-update# ~event)))))
Но в конце я не уверен, что вашему коду нужен макрос, вы пытались написать его как функцию:
(defn add-map-listener [component insert-fn update-fn]
(.addMapListener component
(proxy [AbstractMapListener] []
(entryInserted [e] (insert-fn e))
(entryUpdated [e] (update-fn e)))))
Как вы видели, я изменил пару вещей:
- Сделав имя функции более понятным, ваш макрос не был действительно похож на другие макросы с - *, которые обычно оценивают некоторый код (
body
) в каком-то особом контексте. - Удалил аргумент события, так как казалось, что он не имеет никакого смысла.
- Сделал аргументы insert-fn и update-fn явными дляупростить пример.
- Использовал новый метод, вызывающий синтаксис.
- Исправлены методы прокси для фактического использования данных функций.
Если вы хотите сделать функцииполностью необязательный и дает возможность быть заданным в любом порядке, вы всегда можете сделать это:
(defn add-map-listener [component & functions]
(let [{:keys [insert-fn update-fn]} (into {} functions)]
(when-not (empty? functions)
(.addMapListener component
(proxy [AbstractMapListener] []
(entryInserted [e] (insert-fn e))
(entryUpdated [e] (update-fn e)))))))
Обратите внимание, что я добавил код, чтобы не вызывать addMapListener, когда функции не заданы.