Clojure: Наблюдатели

Помимо атомов и агентов, в Clojure существуют наблюдатели, их основное использование заключается в наблюдении за изменяемым ресурсом (издалека напоминает супервизоров из Elixir/Erlang, но более простых).

Рассмотрим несколько примеров:

(def my-atom (atom 0))

; добавим наблюдателя для нашего атома, у наблюдателя должно быть уникальное имя
(add-watch my-atom "my-watcher"
; обратите внимание на аргументы, которые передаются в функцию, вызываемую наблюдателем при изменении состояния
  (fn [key variable old-state new-state]
    (println key variable old-state new-state)))
#object[clojure.lang.Atom 0x673d073a {:status :ready, :val 0}]

(swap! my-atom inc)
my-watcher #object[clojure.lang.Atom 0x673d073a {:status :ready, :val 1}] 0 1
1

(swap! my-atom (fn [state] (* state 4)))
my-watcher #object[clojure.lang.Atom 0x673d073a {:status :ready, :val 4}] 1 4
4

(swap! my-atom (fn [state] (* state 4)))
my-watcher #object[clojure.lang.Atom 0x673d073a {:status :ready, :val 16}] 4 16
16

; теперь уберем наблюдателя
(remove-watch my-atom "my-watcher")
#object[clojure.lang.Atom 0x673d073a {:status :ready, :val 16}]

(swap! my-atom inc)
17

Наблюдатели позволяют упростить процесс логирования и отладки и сделать жизнь разработчика чуть легче, однако, никто не мешает добавить в функцию наблюдателя какие-либо внешние мутации (например, мутация другого ресурса), но лучше так не делать :)

Задание

Создайте атом (начальное значение 0) и добавьте к нему наблюдателя, который при изменении атома выводит сообщение (с помощью print) в следующем виде Change state from x to y., где x — прошлое состояние атома, а y — новое состояние атома. Затем дважды увеличьте атом на 1, потом уменьшите его значение на 1.

Как с вами связаться? 🙃

Команда проекта находится в телеграм-сообществе по ссылке https://ttttt.me/HexletLearningBot. Там можно задать любой вопрос и повлиять на проект

Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "Обсуждение". Как правильно задать вопрос:

В моей среде код работает, а здесь нет 🤨

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

Мой код отличается от решения учителя 🤔

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

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются

Привет! Я Тота и моя задача помочь в обучении. Чтобы активировать меня, нужно зарегистрироваться или залогиниться, если у вас уже есть аккаунт

Loading...

Ваше упражнение проверяется по этим тестам

1(ns watchers-test
2  (:require [test-helper :refer [assert-output]]))
3
4(assert-output "Change state from 0 to 1.Change state from 1 to 2.Change state from 2 to 1.")
5

Решение учителя откроется через:

20:00
waiting_clock