Here's an example that sandwiches our function call between some logging and some context management:
logger('start');
context_push();
do_stuff(data);
context_pop();
logger('done');
This kind of code gets dangerous if you have to repeat it. The problem is that we really want precisely that order of the surrounding functions. It's easy to transpose lines, or to update the pattern in some places but not others.
Functions come to our aid allowing us to write something like this:
logged(contextualised(do_stuff))(data);
That will guarantee the sandwiching, the first call will be matched by the last call, the next inner pair will match, and so forth. But actually writing those functions will add some code.
function logged(fn) {
return function() {
logger('start');
fn.apply(null, arguments);
logger('done');
}
}
function contextualised(fn) {
return function() {
context_push();
fn.apply(null, arguments);
context_pop();
}
}
The real value here is reuse. We can easily wrap any function now. And we don't have to call our function immediately, we can take the wrapped result and pass it as a parameter where ever it might be useful.
We can even make a general purpose function that create tools like logged and contextualised. I'll show an example of that when I talk about currying functions.
No comments:
Post a Comment