Skip to content

Instantly share code, notes, and snippets.

@gerardpaapu
Created August 16, 2011 23:58
Show Gist options
  • Save gerardpaapu/1150474 to your computer and use it in GitHub Desktop.
Save gerardpaapu/1150474 to your computer and use it in GitHub Desktop.
Function.getMetadata
(function () {
// Reading Function Metadata
// =========================
//
// !!!!! DO NOT USE ANY OF THIS CODE FOR ANY PURPOSE IT WILL EAT YOU KIDS
//
// Because `Function.prototype.toString()` returns something like
// function source-code, we can parse it for metadata like the names of
// the formal arguments or the name of the function.
//
// From Ecma-262 15.3.4.2 'Function.prototype.toString()'
//
// > An implementation-dependent representation of the function is
// > returned. This representation has the syntax of a
// > `FunctionDeclaration`. Note in particular that the use and placement of
// > white space, line terminators, and semicolons within the
// > representation String is implementation-dependent
//
// So strictly speaking, I'm pretty sure we can't rely on this behaviour at all
// in any context, but... it *seems* to work. ^_^ ;;;
var function_pattern, function_to_string;
Function.getMetadata = function (f) {
/*jshint eqnull: true */
var match = function_pattern.exec( function_to_string.call(f) );
if (! match) throw "YOU NEVER SHOULD HAVE DONE THIS";
return {
args: match[2] == null ? [] : match[2].replace(/\s+/g, '').split(','),
name: match[1].length > 0 ? match[1] : null
};
};
// If you call this on a non-function it should throw a `TypeError` immediately
function_to_string = (function (){}).toString;
// This RegExp is used to "parse" the head of a function according to this grammar:
//
// 'function' <symbol> '(' (<symbol> [',' <symbol>]* )? ')'
//
// match[1] should contain the name (or empty string)
// match[2] should contain the args (or null)
function_pattern = /^\s*function\s*(\w*)\s*\(\s*(\w+(\s*,\s*\w+)*)?\s*\)/;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment