diff --git a/README.md b/README.md
index a526e93..04ea10d 100644
--- a/README.md
+++ b/README.md
@@ -13,12 +13,14 @@
* [ Generation.isGeneration(test) ](#generation-is-generation)
* [ Class: Creation ](#class-creation)
* [ Creation.defineProperties([descriptor,] properties) ](#creation-define-properties)
+ * [ Creation.getProto() ](#creation-get-proto)
+ * [ Creation.getSuper() ](#creation-get-super)
+
-Generator
-=========
+# Generator
-An easy to use prototypal inheritance model and generator. All generations inherit from Generator.
+An easy to use prototypal inheritance model and generator. All generations inherit from Generator.
### Install:
```
@@ -41,8 +43,8 @@ var Person = Generator.generate(
/* create method */
function Person(name, age, sex) {
this.name = name || 'no-name';
- this.age = age || 0;
- this.sex = sex || 'unknown';
+ this.age = age || 0;
+ this.sex = sex || 'unknown';
}
);
```
@@ -69,7 +71,7 @@ Example:
```javascript
// generatorize NodeJS' EventEmitter
var Generator = require('generate-js'),
- events = require('events');
+ events = require('events');
var EventEmitter = Generator.toGenerator(events.EventEmitter);
@@ -173,8 +175,8 @@ jim.name // 'Jim'
jim.age // 10
jim.sex // 'male'
-jim.sayHello(); // prints out: 'Hello, my name is Jim. What is yours?'
-jim.sayBye(); // prints out: 'Goodbye.'
+jim.sayHello(); // prints out: 'Hello, my name is Jim. What is yours?'
+jim.sayBye(); // prints out: 'Goodbye.'
```
@@ -211,9 +213,9 @@ Student.definePrototype(
var sarah = Student.create('Sarah', 17, 'female', 'A0123456789');
-sarah.name // 'Sarah'
-sarah.age // 17
-sarah.sex // 'female'
+sarah.name // 'Sarah'
+sarah.age // 17
+sarah.sex // 'female'
sarah.studentId // 'A0123456789'
sarah.sayHello(); // prints out: 'Sup? My student ID is: A0123456789'
@@ -282,6 +284,20 @@ sarah.defineProperties(
```
+
+## Creation.getProto()
+
+* *return*: `Object` Prototype of *this* Creation.
+
+Returns the prototype of *this* Creation.
+
+
+## Creation.getSuper()
+
+* *return*: `Object` super Prototype of *this* Creation.
+
+Returns the super prototype of *this* Creation.
+
## Author:
Michaelangelo Jong
diff --git a/generate.js b/generate.js
index b62e510..cd7eb56 100644
--- a/generate.js
+++ b/generate.js
@@ -6,18 +6,32 @@
(function GeneratorScope() {
// Variables
-var Generator = {},
- GeneratorMethods = {},
- GeneratorProto = {};
+var Creation = {},
+ Generation = {},
+ Generator = {};
// Helper Methods
/**
- * Generator.toString method.
- * @return {String} A string representation of this generator.
+ * Assert Error function.
+ * @param {Boolean} condition Whether or not to throw error.
+ * @param {String} message Error message.
*/
-function toString() {
- return '[' + (this.name || 'generator') + ' Generator]';
+function assertError(condition, message) {
+ if (!condition) {
+ throw new Error(message);
+ }
+}
+
+/**
+ * Assert TypeError function.
+ * @param {Boolean} condition Whether or not to throw error.
+ * @param {String} message Error message.
+ */
+function assertTypeError(test, type) {
+ if (typeof test !== type) {
+ throw new TypeError('Expected \'' + type + '\' but instead found \'' + typeof test +'\'');
+ }
}
/**
@@ -102,130 +116,9 @@ function defineObjectProperties(obj, descriptor, properties) {
return obj;
}
-/**
- * Generates a new generator that inherits from 'ParentGenerator'.
- * @param {Generator} ParentGenerator Generator to inherit from.
- * @param {Function} create Create method that gets called when creating a new instance of new generator.
- * @param {Function} init Inits any data stores needed by prototypal methods.
- * @return {Generator} New Generator that inherits from 'ParentGenerator'.
- */
-function GeneratorFunc(ParentGenerator, create) {
- ParentGenerator = Generator.isGenerator(ParentGenerator) ? ParentGenerator : Generator;
- var proto = Object.create(ParentGenerator.proto),
- properties = Object.create(ParentGenerator.proto.prototypeProperties),
- generator = Object.create(proto);
-
- create = typeof create === 'function' ? create : Generator.proto.__create;
-
- defineObjectProperties(
- properties,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- generator: generator
- }
- );
-
- defineObjectProperties(
- proto,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- proto: ParentGenerator.proto,
- prototypeProperties: properties,
- __parentGenerator: ParentGenerator,
- __create: create,
- }
- );
-
- defineObjectProperties(
- generator,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- name: getFunctionName(create),
- proto: proto
- }
- );
-
- return generator;
-}
-
-/**
- * [toGenerator description]
- * @param {Function} constructor A constructor function.
- * @return {Generator} A new generator who's create method is `constructor` and inherits from `constructor.prototype`.
- */
-function toGenerator(constructor) {
- var proto = Object.create(Generator.proto),
- properties = Object.create(constructor.prototype),
- generator = Object.create(proto);
-
- defineObjectProperties(
- properties,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- generator: generator
- }
- );
-
- defineObjectProperties(
- properties,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- Generator.proto.prototypeProperties
- );
-
- defineObjectProperties(
- proto,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- proto: Generator.proto,
- prototypeProperties: properties,
- __parentGenerator: Generator,
- __create: constructor,
- }
- );
-
- defineObjectProperties(
- generator,
- {
- configurable: false,
- enumerable: false,
- writable: false
- },
- {
- name: getFunctionName(constructor),
- proto: proto
- }
- );
-
- return generator;
-}
-
-// Generator Instance Inheritance
+// Creation Class
defineObjectProperties(
- GeneratorMethods,
+ Creation,
{
configurable: false,
enumerable: false,
@@ -241,67 +134,122 @@ defineObjectProperties(
defineProperties: function defineProperties(descriptor, properties) {
defineObjectProperties(this, descriptor, properties);
return this;
+ },
+
+ /**
+ * returns the prototype of `this` Creation.
+ * @return {Object} Prototype of `this` Creation.
+ */
+ getProto: function getProto() {
+ return Object.getPrototypeOf(this);
+ },
+
+ /**
+ * returns the prototype of `this` super Creation.
+ * @return {Object} Prototype of `this` super Creation.
+ */
+ getSuper: function getSuper() {
+ return Object.getPrototypeOf(this.generator).proto;
+ // return Object.getPrototypeOf(Object.getPrototypeOf(this));
}
}
);
-// Generator Base Inheritance
+// Generation Class
defineObjectProperties(
- GeneratorProto,
+ Generation,
{
configurable: false,
enumerable: false,
writable: false
},
{
- prototypeProperties: GeneratorMethods,
+ name: 'Generation',
+
+ proto: Creation,
+
/**
* Creates a new instance of this Generator.
* @return {Generator} Instance of this Generator.
*/
create: function create() {
var _ = this,
- args = Array.prototype.slice.call(arguments),
- newObj = Object.create(_.proto.prototypeProperties);
+ newObj = Object.create(_.proto);
- _.__supercreate.apply(newObj, [_].concat(args));
+ _.__supercreate(newObj, arguments);
return newObj;
},
- __supercreate: function __supercreate(generator) {
+
+ __supercreate: function __supercreate(newObj, args) {
var _ = this,
- args = Array.prototype.slice.call(arguments).slice(1),
- parentGenerator = generator.__parentGenerator,
+ superGenerator = Object.getPrototypeOf(_),
supercreateCalled = false;
- _.supercreate = function supercreate() {
- var args = Array.prototype.slice.call(arguments);
+ newObj.supercreate = function supercreate() {
supercreateCalled = true;
- if (Generator.isGenerator(parentGenerator)){
- parentGenerator.__supercreate.apply(_, [parentGenerator].concat(args));
+ if (Generation.isGeneration(superGenerator)){
+ superGenerator.__supercreate(newObj, arguments);
}
};
- generator.__create.apply(_, args);
+ _.__create.apply(newObj, args);
if (!supercreateCalled) {
- _.supercreate();
+ newObj.supercreate();
}
- delete _.supercreate;
+ delete newObj.supercreate;
},
+
__create: function () {},
+
/**
- * Returns a new Generator that inherits from this Generator.
- * @param {Function} create Create method that gets called when creating a new instance of new generator.
- * @param {Function} init Inits any data stores needed by prototypal methods.
- * @return {Generator} New generator that inherits from this Generator.
+ * Generates a new generator that inherits from `this` generator.
+ * @param {Generator} ParentGenerator Generator to inherit from.
+ * @param {Function} create Create method that gets called when creating a new instance of new generator.
+ * @return {Generator} New Generator that inherits from 'ParentGenerator'.
*/
- generate:function generate(create, init) {
- return GeneratorFunc(this, create, init);
+ generate: function generate(create) {
+ var _ = this;
+
+ assertError(Generation.isGeneration(_) || _ === Generation, 'Cannot call method \'generate\' on non-Generations.');
+ assertTypeError(create, 'function');
+
+ var newGenerator = Object.create(_),
+ newProto = Object.create(_.proto);
+
+ defineObjectProperties(
+ newProto,
+ {
+ configurable: false,
+ enumerable: false,
+ writable: false
+ },
+ {
+ generator: newGenerator
+ }
+ );
+
+ defineObjectProperties(
+ newGenerator,
+ {
+ configurable: false,
+ enumerable: false,
+ writable: false
+ },
+ {
+ name: getFunctionName(create),
+ proto: newProto,
+ __create: create
+ }
+ );
+
+ return newGenerator;
},
+
/**
* Returns true if 'generator' was generated by this Generator.
* @param {Generator} generator A Generator.
@@ -309,16 +257,9 @@ defineObjectProperties(
*/
isGeneration: function isGeneration(generator) {
var _ = this;
- if (generator && typeof generator === 'object' && _ !== generator) {
- while (generator.__parentGenerator && typeof generator.__parentGenerator === 'object') {
- generator = generator.__parentGenerator;
- if (_ === generator) {
- return true;
- }
- }
- }
- return false;
+ return _.isPrototypeOf(generator);
},
+
/**
* Returns true if 'object' was created by this Generator.
* @param {Object} object An Object.
@@ -326,12 +267,9 @@ defineObjectProperties(
*/
isCreation: function isCreation(object) {
var _ = this;
-
- if (object && typeof object === 'object' && Generator.isGenerator(object.generator)) {
- return _ === object.generator || _.isGeneration(object.generator);
- }
- return false;
+ return _.proto.isPrototypeOf(object);
},
+
/**
* Defines shared properties for all objects created by this generator.
* @param {Object} descriptor Optional object descriptor that will be applied to all attaching properties.
@@ -339,10 +277,17 @@ defineObjectProperties(
* @return {Generator} This generator.
*/
definePrototype: function definePrototype(descriptor, properties) {
- defineObjectProperties(this.proto.prototypeProperties, descriptor, properties);
+ defineObjectProperties(this.proto, descriptor, properties);
return this;
},
- toString: toString
+
+ /**
+ * Generator.toString method.
+ * @return {String} A string representation of this generator.
+ */
+ toString: function toString() {
+ return '[' + (this.name || 'generation') + ' Generator]';
+ }
}
);
@@ -355,15 +300,82 @@ defineObjectProperties(
writable: false
},
{
- name: 'Generator',
- proto: GeneratorProto,
- generate: GeneratorProto.generate,
- isGenerator: GeneratorProto.isGeneration,
- toGenerator: toGenerator,
- toString: toString
+ /**
+ * Generates a new generator that inherits from `this` generator.
+ * @param {Generator} ParentGenerator Generator to inherit from.
+ * @param {Function} create Create method that gets called when creating a new instance of new generator.
+ * @return {Generator} New Generator that inherits from 'ParentGenerator'.
+ */
+ generate: function generate (create) {
+ return Generation.generate(create);
+ },
+
+ /**
+ * Returns true if 'generator' was generated by this Generator.
+ * @param {Generator} generator A Generator.
+ * @return {Boolean} true or false.
+ */
+ isGenerator: function isGenerator (generator) {
+ return Generation.isGeneration(generator);
+ },
+
+ /**
+ * [toGenerator description]
+ * @param {Function} constructor A constructor function.
+ * @return {Generator} A new generator who's create method is `constructor` and inherits from `constructor.prototype`.
+ */
+ toGenerator: function toGenerator(constructor) {
+
+ assertTypeError(constructor, 'function');
+
+ var newGenerator = Object.create(Generation),
+ newProto = Object.create(constructor.prototype);
+
+ defineObjectProperties(
+ newProto,
+ {
+ configurable: false,
+ enumerable: false,
+ writable: false
+ },
+ {
+ generator: newGenerator
+ }
+ );
+
+ defineObjectProperties(
+ newProto,
+ {
+ configurable: false,
+ enumerable: false,
+ writable: false
+ },
+ Creation
+ );
+
+ defineObjectProperties(
+ newGenerator,
+ {
+ configurable: false,
+ enumerable: false,
+ writable: false
+ },
+ {
+ name: getFunctionName(constructor),
+ proto: newProto,
+ __create: constructor
+ }
+ );
+
+ return newGenerator;
+ }
}
);
+Object.freeze(Creation);
+Object.freeze(Generation);
+Object.freeze(Generator);
+
// Exports
if (typeof define === 'function' && define.amd) {
// AMD
diff --git a/package.json b/package.json
index ce387d1..0da8448 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "generate-js",
- "version": "2.0.4",
+ "version": "2.1.0",
"description": "An easy to use prototypal inheritance model and generator.",
"main": "generate.js",
"scripts": {