Created
August 16, 2011 23:58
-
-
Save gerardpaapu/1150474 to your computer and use it in GitHub Desktop.
Function.getMetadata
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 characters
(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