Last active
August 29, 2015 14:08
-
-
Save marlun78/3a79b98370c05e982696 to your computer and use it in GitHub Desktop.
Simple meta-programming for methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Intercept.js | |
* Simple meta-programming for methods | |
* Copyright (c) 2014 marlun78 | |
* MIT License, https://gist.github.com/marlun78/bd0800cf5e8053ba9f83 | |
* | |
* The intercept-function provides a pre and a post hook that | |
* will run before and after the original implementation | |
* respectively. In the pre-hook you have access to the | |
* arguments passed, and in the post-hook you have access to | |
* both the arguments and the value returned by the original | |
* implementation. | |
* | |
* @example | |
* var math = { add: function add(a, b) { return a + b; } }; | |
* var revert = intercept(math, 'add', pre, post); | |
* function pre(config) { console.log('Pre', config); } | |
* function post(config) { console.log('Post', config); } | |
* math.add(1, 2); | |
* // Pre, { args: [1, 2] } | |
* // Post, { args: [1, 2], returned: 3 } | |
* // 3 | |
* revert(); | |
* math.add(2, 3); | |
* // 5 | |
* | |
* @param {Object} host - The object where the method lives in | |
* @param {String} name - The name of the method to intercept | |
* @param {Function} pre - A function to be called _before_ the original implementation | |
* @param {Function} post - A function to be called _after_ the original implementation | |
* @param {Boolean} once - Should this be reverted after the first call? | |
* @returns {Function} - A revert function | |
*/ | |
var intercept = (function () { | |
'use strict'; | |
var slice = Array.prototype.slice; | |
return function intercept(host, name, pre, post, once) { | |
var originalMethod = host[name]; | |
if (isFunction(originalMethod)) { | |
host[name] = intercepted; | |
return revert; | |
} | |
return noop; | |
function intercepted() { | |
var config = { args: toArray(arguments) }; | |
if (once === true) revert(); | |
if (isFunction(pre)) pre.call(this, config); | |
config.returned = originalMethod.apply(this, config.args || []); | |
if (isFunction(post)) post.call(this, config); | |
return config.returned; | |
} | |
function revert() { | |
host[name] = originalMethod; | |
} | |
}; | |
function noop() {} | |
function isFunction(value) { | |
return typeof value === 'function'; | |
} | |
function toArray(value) { | |
return slice.call(value); | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment