Created
June 19, 2009 18:43
-
-
Save silentmatt/132782 to your computer and use it in GitHub Desktop.
Revisions
-
silentmatt created this gist
Jun 19, 2009 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ /* Get an array of parameter names for a function. Example: js> function f(a, b, c) { return a + b * c; } js> JSON.stringify(Function.parameters(f)); ["a","b","c"] */ Function.parameters = function(f) { var m = /function[^\(]*\(([^\)]*)\)/.exec(f.toString()); if (!m) { throw new TypeError("Invalid function in parameters"); } var params = m[1].split(','); for (var i = 0; i < params.length; i++) { // trim any spaces params[i] = params[i].replace(/^\s*|\s*$/g, ''); } return params; }; /* Create a new function that accepts its parameters in an object instead of its positional parameters. An optional array of names can be provided instead of using the parameters defined in the function (to rename parameters, or since some functions might use parameters that aren't named). Examples: js> function f(a, b, c) { return a + b * c; } js> f(1, 2, 3); 7 js> var f1 = Function.withNamedParameters(f); js> f1({ a:1, b:2, c:3 }); 7 js> // Call with an array (like f.apply) js> var f2 = Function.withNamedParameters(f, [0, 1, 2]); js> f2([1, 2, 3]); 7 */ Function.withNamedParameters = function(f, params) { // XXX: should this force f to be a function, or should anything that passes // the parameters RegExp with an apply function work? params = params || Function.parameters(f); return function(args) { var argsArray = new Array(params.length); for (var i = 0; i < params.length; i++) { argsArray[i] = args[params[i]]; } return f.apply(this, argsArray); }; }; /* Create a new function that accepts its positional parameters as objects mapping parameter names to values. Each parameter array maps ascending arguments to properties in an object. With a single parameter array, this is the opposite of Function.withNamedParameters. Examples: js> function f(p1, p2) { return { x: p1.x + p2.x, y: p1.y + p2.y }; } js> var f1 = Function.withPositionalParameters(f, ["x","y"], ["x","y"]); js> JSON.stringify(f1(1, 2, 3, 4)); {"x":4,"y":6} js> function f(a, b, c) { return a + b * c; } js> var f1 = Function.withNamedParameters(f); js> var f2 = Function.withPositionalParameters(f1, ["a", "b", "c"]); js> f2(1, 2, 3); // f2 is equivalent to (but slower than) f 7 js> // Reorder parameters js> var f3 = Function.withPositionalParameters(f1, ["c", "b", "a"]); js> f3(3, 2, 1); 7 */ Function.withPositionalParameters = function(f, params /*, ... */) { params = Array.prototype.slice.call(arguments, 1); return function() { var args = []; var argumentsIndex = 0; for (var i = 0; i < params.length; i++) { var arg = {}; var paramList = params[i]; args.push(arg); for (var p = 0; p < paramList.length; p++) { arg[paramList[p]] = arguments[argumentsIndex]; ++argumentsIndex; } } return f.apply(this, args); }; };