forked from TooTallNate/node-function-class
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 629ab23
Showing
5 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
node-function-class | ||
=================== | ||
### Easy `Function` subclasses | ||
[](http://travis-ci.org/TooTallNate/node-function-class) | ||
|
||
Creates a function instance with specified `name` and `length` and `prototype` | ||
|
||
Installation | ||
------------ | ||
|
||
Install with `npm`: | ||
|
||
``` bash | ||
$ npm install array-index | ||
``` | ||
|
||
|
||
Examples | ||
-------- |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
var crypto = require('crypto'); | ||
var setFunctionName = require('function-name'); | ||
var setPrototypeOf = require('setprototypeof'); | ||
|
||
module.exports = exports = createFunctionInstance; | ||
var invoke = exports.invoke = require('./invoke'); | ||
|
||
function createFunctionInstance (constructor, args, name, length) { | ||
var fn = functionNameArity(name, length, function () { | ||
return fn[invoke].apply(fn, arguments); | ||
}); | ||
setPrototypeOf(fn, constructor.prototype); | ||
|
||
var rtn = constructor.apply(fn, args); | ||
|
||
if (typeof rtn !== 'undefined') { | ||
return rtn; | ||
} else { | ||
return fn; | ||
} | ||
} | ||
|
||
function randomIdentifier (length) { | ||
var id; | ||
do { | ||
id = crypto.randomBytes(length / 2).toString('hex'); | ||
} while (/\d/.test(id[0])); | ||
return id; | ||
} | ||
|
||
function functionNameArity (name, arity, fn) { | ||
var tempName, args; | ||
|
||
if (name) { | ||
tempName = randomIdentifier(20); | ||
} else { | ||
tempName = ''; | ||
} | ||
|
||
if (typeof arity === 'number') { | ||
args = []; | ||
while (arity--) args.push('_'); | ||
args = args.join(','); | ||
} else { | ||
args = ''; | ||
} | ||
|
||
var proxy = new Function('fn', | ||
'return function ' + tempName + '(' + args + '){' + | ||
'return fn.apply(this,arguments)' + | ||
'}')(fn); | ||
|
||
if (name) setFunctionName(proxy, name); | ||
|
||
return proxy; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
var Symbol = require('es6-symbol'); | ||
module.exports = Symbol('invoke'); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "function-class", | ||
"version": "1.0.0", | ||
"description": "Easy `Function` subclasses", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/TooTallNate/node-function-class.git" | ||
}, | ||
"keywords": [ | ||
"function", | ||
"create", | ||
"name", | ||
"arity", | ||
"length", | ||
"instance", | ||
"subclass", | ||
"prototype", | ||
"inheritance" | ||
], | ||
"author": "Nathan Rajlich <[email protected]>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/TooTallNate/node-function-class/issues" | ||
}, | ||
"homepage": "https://github.com/TooTallNate/node-function-class#readme", | ||
"dependencies": { | ||
"es6-symbol": "^3.0.2", | ||
"function-name": "^1.0.0", | ||
"setprototypeof": "^1.0.0" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
var assert = require('assert'); | ||
var inherits = require('util').inherits; | ||
|
||
var createFunctionInstance = require('./'); | ||
var invoke = require('./invoke'); | ||
|
||
function Type (name, length) { | ||
if (typeof this !== 'function') | ||
return createFunctionInstance(Type, arguments, name, length); | ||
|
||
this.count = 0; | ||
} | ||
inherits(Type, Function); | ||
|
||
Type.prototype[invoke] = function (val) { | ||
this.count += val; | ||
}; | ||
|
||
|
||
|
||
var t1 = new Type('nate', 6); | ||
assert.ok(t1 instanceof Type); | ||
assert.ok(t1 instanceof Function); | ||
assert.ok(t1 instanceof Object); | ||
assert.equal(t1.name, 'nate'); | ||
assert.equal(t1.length, 6); | ||
assert.equal(t1.count, 0); | ||
t1(5); | ||
assert.equal(t1.count, 5); | ||
|
||
var t2 = new Type('foo', 6); | ||
assert.ok(t2 instanceof Type); | ||
assert.ok(t2 instanceof Function); | ||
assert.ok(t2 instanceof Object); | ||
assert.equal(t2.name, 'foo'); | ||
assert.equal(t2.length, 6); | ||
assert.equal(t2.count, 0); | ||
t2(-1); | ||
assert.equal(t2.count, -1); | ||
|
||
|
||
|
||
function Subclass (init) { | ||
if (typeof this !== 'function') | ||
return createFunctionInstance(Subclass, arguments, 'sub', 100); | ||
Type.call(this); | ||
this.count = init; | ||
} | ||
inherits(Subclass, Type); | ||
|
||
var s1 = new Subclass(6); | ||
assert.ok(s1 instanceof Subclass); | ||
assert.ok(s1 instanceof Type); | ||
assert.ok(s1 instanceof Function); | ||
assert.ok(s1 instanceof Object); | ||
assert.equal(s1.name, 'sub'); | ||
assert.equal(s1.length, 100); | ||
assert.equal(s1.count, 6); | ||
s1(-1); | ||
assert.equal(s1.count, 5); |