Skip to content

Instantly share code, notes, and snippets.

@luciferous
Created May 6, 2011 08:19
Show Gist options
  • Save luciferous/958603 to your computer and use it in GitHub Desktop.
Save luciferous/958603 to your computer and use it in GitHub Desktop.
Decorators for Javascript a la Python

Decorators for Javascript ala Python

Imagine a function named foo that takes two parameters, prints them to a console, and returns a boolean true if the two parameters are equal:

function foo(a, b) {
    console.log([a, b]);
    return a === b;
}

A test run produces the following output:

> foo(1, 2);
[1, 2]
false

The decorator accepts enforces the type of the arguments passed in. It can be used to require the two arguments to strings and return a boolean.

decorate(window, "foo", accepts("string", "string"), returns("boolean"));

Now the previous test run will produce an error:

> foo(1, 2);
TypeError: arg 0 does not match string

References

function decorate() {
var args = Array.prototype.slice.call(arguments);
var obj = args.shift(),
fnName = args.shift();
if (!(obj && fnName)) {
return;
}
var fn = obj[fnName];
for (var i = 0; i < args.length; i++) {
var wrap = args[i];
fn = wrap(fn);
}
obj[fnName] = fn;
}
function accepts() {
var types = Array.prototype.slice.call(arguments);
return function(fn) {
var newFn = function() {
var args = Array.prototype.slice.call(arguments);
if (args.length != types.length) {
throw "not enough arguments";
}
for (var i = 0; i < args.length; i++) {
var arg = args[i],
type = types[i];
if (typeof arg != type) {
throw new TypeError("arg " + i +
" does not match " + type);
}
}
return fn.apply(fn, args);
};
return newFn;
};
}
function returns(rtype) {
return function(f) {
function newFn() {
var args = Array.prototype.slice.call(arguments);
var result = f.apply(fn, args);
if (typeof result != rtype) {
throw new TypeError("return value " + result +
" does not match" + rtype);
}
return result;
}
return newFn;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment