Skip to content
This repository has been archived by the owner on Jul 27, 2020. It is now read-only.

Commit

Permalink
Add named hooks support
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitri Naumov committed May 17, 2012
1 parent 0dda144 commit 9feaeda
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
25 changes: 11 additions & 14 deletions src/robert/hooke.clj
Original file line number Diff line number Diff line change
Expand Up @@ -36,43 +36,40 @@
(reduce compose-hooks original hooks))

(defn- run-hooks [hook original args]
(apply (join-hooks original @hook) args))
(apply (join-hooks original (vals @hook)) args))

(defn- prepare-for-hooks [v]
(when-not (:robert.hooke/hook (meta @v))
(let [hook (atom ())]
(let [hook (atom {})]
(alter-var-root v (fn [original]
(with-meta
(fn [& args]
(run-hooks hook original args))
(assoc (meta original)
:robert.hooke/hook hook
:robert.hooke/original original)))))))

(defn- add-unless-present [coll f]
(if-not (some #{f} coll)
(conj coll f)
coll))
:robert.hooke/original original)))))))

(defn add-hook
"Add a hook function f to target-var. Hook functions are passed the
target function and all their arguments and must apply the target to
the args if they wish to continue execution."
[target-var f]
(prepare-for-hooks target-var)
(swap! (:robert.hooke/hook (meta @target-var)) add-unless-present f))
([target-var f]
(add-hook target-var f f))
([target-var key f]
(prepare-for-hooks target-var)
(swap! (:robert.hooke/hook (meta @target-var)) assoc key f)))

(defn- clear-hook-mechanism [target-var]
(alter-var-root target-var
(constantly (:robert.hooke/original
(meta @target-var)))))

(defn remove-hook
"Remove hook function f from target-var."
[target-var f]
"Remove hook identified by key from target-var."
[target-var key]
(when (:robert.hooke/hook (meta @target-var))
(swap! (:robert.hooke/hook (meta @target-var))
(partial remove #{f}))
dissoc key)
(when (empty? @(:robert.hooke/hook (meta @target-var)))
(clear-hook-mechanism target-var))))

Expand Down
13 changes: 13 additions & 0 deletions test/robert/test_hooke.clj
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,16 @@
(deftest hooks-disabled-works-around-test-selectors
(with-hooks-disabled test-var
(skipped)))

(defn keyed [x] x)

(deftest test-hooks-with-keys
(is (= (keyed 1) 1))
(add-hook #'keyed :inc (fn [f x] (f (inc x))))
(is (= (keyed 1) 2))
(add-hook #'keyed :add-3 (fn [f x] (f (+ 3 x))))
(is (= (keyed 1) 5))
(remove-hook #'keyed :inc)
(is (= (keyed 1) 4))
(clear-hooks)
(is (= (keyed 1) 1)))

0 comments on commit 9feaeda

Please sign in to comment.