предположим, у меня есть var atom-var
(def atom-val (atom []))
Также предположим стандартное поведение атома:
(swap! atom-val conj {:b "2"})
=> #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}]
(@atom-val)
=> #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}]
Я хочу создать такое же поведение, с которым оно будет работатьобъект nil, но без действий:
(def atom-val nil)
(swap! atom-val conj "New val")
Конечно, я получу исключение NullPointerException.Но я хочу, чтобы ничего не случилось, подавить это.Мне не нужно каждый раз писать try, мне просто нужно описанное поведение.
Я вижу, что swap! - это функция, atom - это функция,атом возвращает clojure.lang.IAtom , clojure.lang.IAtom является интерфейсом.Я не могу расширить интерфейс.Как я могу получить описанное поведение?
Хорошо, у меня есть глобальная динамическая переменная, равная nil
(def ^:dynamic atom-val nil).
Всякий раз, когда создается поток (это обработчик кольца с compojure), яЯ связываю atom-val с
(defn func [handler]
(fn [request]
(binding [atom-val (atom [])]
(handler request)
)
)
Итак, у меня есть такая форма в различных функциях:
(swap! atom-val conj "New val").
Я могу запускать ее везде много раз (внутри / снаружи разных функций),Очень плохо каждый раз проверять, является ли atom-val нулевым или нет.Функции могут сделать swap! , но иногда atom-val не может быть правильно инициализирован (когда функция выполняет своп! Вне обработчиков кольца перед привязкой).
Итак, я решил сделать это следующим образом: я бы хотел расширить протокол swap! для Atom и когда nil (когда atom-val
равен nil )он не должен выдавать исключение NullPointerException.