3 Monkey-patch (hook) functions for debugging and stuff.
7 This code should work just fine in Node.js:
9 First, install the module with: `npm install hooker`
12 var hooker = require('hooker');
13 hooker.hook(Math, "max", function() {
14 console.log(arguments.length + " arguments passed");
16 Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
22 <script src="dist/ba-hooker.min.js"></script>
24 hook(Math, "max", function() {
25 console.log(arguments.length + " arguments passed");
27 Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
31 In the browser, you can attach Hooker's methods to any object.
35 this.exports = Bocoup.utils;
37 <script src="dist/ba-hooker.min.js"></script>
39 Bocoup.utils.hook(Math, "max", function() {
40 console.log(arguments.length + " arguments passed");
42 Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
49 Monkey-patch (hook) one or more methods of an object.
51 `hooker.hook(object, [ props, ] [options | prehookFunction])`
53 The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all enumerable methods of `object` will be hooked.
55 * `pre` - (Function) a pre-hook function to be executed before the original function. Arguments passed into the method will be passed into the pre-hook function as well.
56 * `post` - (Function) a post-hook function to be executed after the original function. The original function's result is passed into the post-hook function as its first argument, followed by the method arguments.
57 * `once` - (Boolean) if true, auto-unhook the function after the first execution.
58 * `passName` - (Boolean) if true, pass the name of the method into the pre-hook function as its first arg (preceding all other arguments), and into the post-hook function as the second arg (after result but preceding all other arguments).
61 An array of hooked method names.
64 Un-monkey-patch (unhook) one or more methods of an object.
66 `hooker.unhook(object [, props ])`
68 The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all methods of `object` will be unhooked.
70 An array of unhooked method names.
73 Get a reference to the original method from a hooked function.
75 `hooker.orig(object, props)`
78 When a pre- or post-hook returns the result of this function, the value
79 passed will be used in place of the original function's return value. Any
80 post-hook override value will take precedence over a pre-hook override value.
82 `hooker.override(value)`
85 When a pre-hook returns the result of this function, the value passed will
86 be used in place of the original function's return value, and the original
87 function will NOT be executed.
89 `hooker.preempt(value)`
92 When a pre-hook returns the result of this function, the context and
93 arguments passed will be applied into the original function.
95 `hooker.filter(context, arguments)`
99 See the unit tests for more examples.
102 var hooker = require('hooker');
104 hooker.hook(Math, "max", function() {
105 console.log(arguments.length + " arguments passed");
107 Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7
109 hooker.unhook(Math, "max"); // (This is assumed between all further examples)
110 Math.max(5, 6, 7) // 7
112 // Returning hooker.override(value) overrides the original value.
113 hooker.hook(Math, "max", function() {
114 if (arguments.length === 0) {
115 return hooker.override(9000);
118 Math.max(5, 6, 7) // 7
121 // Auto-unhook after one execution.
122 hooker.hook(Math, "max", {
125 console.log("Init something here");
128 Math.max(5, 6, 7) // logs: "Init something here", returns 7
129 Math.max(5, 6, 7) // 7
131 // Filter `this` and arguments through a pre-hook function.
132 hooker.hook(Math, "max", {
134 var args = [].map.call(arguments, function(num) {
137 return hooker.filter(this, args); // thisValue, arguments
140 Math.max(5, 6, 7) // 14
142 // Modify the original function's result with a post-hook function.
143 hooker.hook(Math, "max", {
144 post: function(result) {
145 return hooker.override(result * 100);
148 Math.max(5, 6, 7) // 700
150 // Hook every Math method. Note: if Math's methods were enumerable, the second
151 // argument could be omitted. Since they aren't, an array of properties to hook
152 // must be explicitly passed. Non-method properties will be skipped.
153 // See a more generic example here: http://bit.ly/vvJlrS
154 hooker.hook(Math, Object.getOwnPropertyNames(Math), {
156 pre: function(name) {
157 console.log("=> Math." + name, [].slice.call(arguments, 1));
159 post: function(result, name) {
160 console.log("<= Math." + name, result);
164 var result = Math.max(5, 6, 7);
165 // => Math.max [ 5, 6, 7 ]
169 result = Math.ceil(3.456);
170 // => Math.ceil [ 3.456 ]
176 In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt).
178 _Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_
181 2012/01/09 - v0.2.3 - First official release.
184 Copyright (c) 2012 "Cowboy" Ben Alman
185 Licensed under the MIT license.
186 <http://benalman.com/about/license/>