Skip to content

Instantly share code, notes, and snippets.

@iamkvein
Created March 9, 2012 14:32
Show Gist options
  • Save iamkvein/2006752 to your computer and use it in GitHub Desktop.
Save iamkvein/2006752 to your computer and use it in GitHub Desktop.
Improved way of temporarily replacing a method on an object
var install_hook_to = function(obj) {
if (obj.hook || obj.unhook) {
throw new Error('Object already has properties hook and/or unhook');
}
obj.hook = function(_meth_name, _fn, _is_async) {
var self = this,
meth_ref;
// Make sure method exists
if (! (Object.prototype.toString.call(self[_meth_name]) === '[object Function]')) {
throw new Error('Invalid method: ' + _meth_name);
}
// We should not hook a hook
if (self.unhook.methods[_meth_name]) {
throw new Error('Method already hooked: ' + _meth_name);
}
// Reference default method
meth_ref = (self.unhook.methods[_meth_name] = self[_meth_name]);
self[_meth_name] = function() {
var args = Array.prototype.slice.call(arguments);
// Our hook should take the same number of arguments
// as the original method so we must fill with undefined
// optional args not provided in the call
while (args.length < meth_ref.length) {
args.push(undefined);
}
// Last argument is always original method call
args.push(function() {
var args = arguments;
if (_is_async) {
process.nextTick(function() {
meth_ref.apply(self, args);
});
} else {
meth_ref.apply(self, args);
}
});
_fn.apply(self, args);
};
};
obj.unhook = function(_meth_name) {
var self = this,
ref = self.unhook.methods[_meth_name];
if (ref) {
self[_meth_name] = self.unhook.methods[_meth_name];
delete self.unhook.methods[_meth_name];
} else {
throw new Error('Method not hooked: ' + _meth_name);
}
};
obj.unhook.methods = {};
};
//// Example ////
var stdout = process.stdout;
install_hook_to(stdout);
console.log('-- Sync');
stdout.hook('write', function(string, encoding, fd, write) {
write('caught: ' + string);
});
console.log('foo');
stdout.unhook('write');
console.log('-- Async');
stdout.hook('write', function(string, encoding, fd, write) {
write('caught async: ' + string);
}, true);
console.log('bar');
stdout.unhook('write');
console.log('baz');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment