Skip to content
Newer
Older
100644 132 lines (94 sloc) 3.94 KB
9d43a2a @technomancy Initial commit.
authored Jun 10, 2010
1 # Robert Hooke
2
3 Robert Hooke provides a flexible, composable mechanism by which you
4 can extend behaviour of functions after they've been defined. It's named
5 after [Robert Hooke FRS](http://en.wikipedia.org/wiki/Robert_Hooke), a
6 founding member of the Royal Society who made many important
7 discoveries in the fields of Gravitation, Microscopy, and Astronomy.
8
7ca2df9 @technomancy Added installation note to readme.
authored Jun 10, 2010
9 Add this to your project.clj :dependencies list:
10
1aec6c8 @technomancy Release 1.1.2, now with Clojure 1.3 compatibility.
authored Jun 30, 2011
11 [robert/hooke "1.1.2"]
7ca2df9 @technomancy Added installation note to readme.
authored Jun 11, 2010
12
24c997a @technomancy Remove redundant readme paragraph.
authored Jun 10, 2010
13 If you would like to make your software extensible using Hooke, all
14 you need to do is provide a convention for namespaces that will get
15 loaded on startup. Then users can place files that call add-hook under
16 a specific namespace prefix (my.program.hooks.*) which they can rely
17 on getting loaded at startup.
7ca2df9 @technomancy Added installation note to readme.
authored Jun 11, 2010
18
8ce1626 @technomancy Readme improvements.
authored Nov 11, 2010
19 Hooks can change the behaviour of the functions they wrap in many
20 ways:
21
22 * binding
23 * conditional execution (may decide not to continue or decide to call
24 a different function in some circumstances)
25 * modify arguments
26 * add side effects
27 * return different value
28
46588f6 @technomancy Fix a docstring bug. Need heredocs.
authored Jun 11, 2010
29 Hooke is inspired by Emacs Lisp's defadvice and clojure.test fixtures.
30
9d43a2a @technomancy Initial commit.
authored Jun 11, 2010
31 ## Usage
32
33 (use 'robert.hooke)
34
35 (defn examine [x]
36 (println x))
37
38 (defn microscope
39 "The keen powers of observation enabled by Robert Hooke allow
40 for a closer look at any object!"
41 [f x]
42 (f (.toUpperCase x)))
43
44 (defn doubler [f & args]
45 (apply f args)
46 (apply f args))
47
48 (defn telescope [f x]
49 (f (apply str (interpose " " x))))
50
d7e96cb Clarify documentation to reflect importance of using Var objects.
Paul Dorman authored Jan 16, 2012
51 (add-hook #'examine #'microscope)
52 (add-hook #'examine #'doubler)
53 (add-hook #'examine #'telescope)
9d43a2a @technomancy Initial commit.
authored Jun 11, 2010
54
55 (examine "something")
56 > S O M E T H I N G
57 > S O M E T H I N G
58
59 Hooks are functions that wrap other functions. They receive the
60 original function and its arguments as their arguments. Hook
61 functions can wrap the target functions in binding, change the
62 argument list, only run the target functions conditionally, or all
63 sorts of other stuff.
64
65 Technically the first argument to a hook function is not always the
66 target function; if there is more than one hook then the first hook
67 will receive a function that is a composition of the remaining
8ce1626 @technomancy Readme improvements.
authored Nov 12, 2010
68 hooks. (Dare I say a continuation?) But when you're writing hooks, you
69 should act as if it is the target function.
70
71 Adding hooks to a defmulti is discouraged as it will make it
72 impossible to add further methods. Hooks are meant to extend functions
73 you don't control; if you own the target function there are obviously
74 better ways to change its behaviour.
75
0000b1d @technomancy Clarify interactive reloading with vars in readme.
authored Jan 15, 2012
76 When adding hooks it's best to use vars instead of raw functions in
77 order to allow the code to be reloaded interactively. If you recompile
78 a function, it will be re-added as a hook, but if you use a var it
79 will be able to detect that it's the same thing across reloads and
80 avoid duplication.
d7e96cb Clarify documentation to reflect importance of using Var objects.
Paul Dorman authored Jan 15, 2012
81
82 (add-hook #'some.ns/target-var #'hook-function)
83
84 instead of:
85
86 (add-hook #'some.ns/target-var hook-function)
87
88
8ce1626 @technomancy Readme improvements.
authored Nov 12, 2010
89 ## Bonus Features
90
91 Most of the time you'll never need more than just add-hook. But
92 there's more!
93
94 If you are using Hooke just to add side-effects to a function, it may
95 be simpler to use the append or prepend macros:
96
97 (prepend print-name
98 (print "The following person is awesome:"))
99
100 (print-name "Gilbert K. Chesterton")
101 > The following person is awesome:
102 > Gilbert K. Chesterton
103
104 You may also run a block of code with the hooks for a given var
105 stripped out:
106
107 (with-hooks-disabled print-name
108 (print-name "Alan Moore"))
109 > Alan Moore
9d43a2a @technomancy Initial commit.
authored Jun 11, 2010
110
9049ac0 @hugoduncan Document hook-scope in README
hugoduncan authored Oct 6, 2012
111 The `hook-scope` macro provides a scope which records any change to hooks during
112 the dynamic scope of its body, and restores hooks to their original state on
113 exit of the scope. Note that all threads share the scope. Using the example
114 functions above:
115
116 (examine "something")
117 > something
118
119 (hook-scope
120 (add-hook #'examine #'microscope)
121 (examine "something"))
122 > SOMETHING
123
124 (examine "something")
125 > something
126
9d43a2a @technomancy Initial commit.
authored Jun 11, 2010
127 ## License
128
0000b1d @technomancy Clarify interactive reloading with vars in readme.
authored Jan 16, 2012
129 Copyright © 2010-2011 Phil Hagelberg and Kevin Downey
9d43a2a @technomancy Initial commit.
authored Jun 11, 2010
130
131 Distributed under the Eclipse Public License, the same as Clojure.
Something went wrong with that request. Please try again.