Skip to content

Instantly share code, notes, and snippets.

@shakirullahi
Forked from m4r00p/r-proto-class.js
Created February 22, 2013 12:41
Show Gist options
  • Save shakirullahi/5013157 to your computer and use it in GitHub Desktop.
Save shakirullahi/5013157 to your computer and use it in GitHub Desktop.
/**
* r-proto-class.js
* Ruby's semantics
*
* Features:
* - super calls
* - using Object.create for inheritance
* - Class.new is a wrapper over Class.allocate and Class.initialize
*
* by Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
* MIT Style License
*/
var Class = {
/**
*allocate
* Creates an instance. Default is
* the implementation of native `new'
*/
allocate: function () {
return Object.create(this);
},
/**
* new
* A wrapper over allocated and initialize
*/
new: function () {
var instance = this.allocate();
this.initialize.apply(instance, arguments);
return instance;
},
/**
* initialize
* Configure a newly created instance
*/
initialize: emptyFn,
/**
* super
*/
super: function (method) {
var parentName = '__' + method + '_invoke__';
var parentObject = this[parentName];
var proto;
if (parentObject) {
// deeper levels
proto = Object.getPrototypeOf(parentObject.proto);
} else {
// first level (proto of an instance) -- get the next level
proto = Object.getPrototypeOf(Object.getPrototypeOf(this));
}
this[parentName] = {proto: proto, level: (parentObject ? parentObject.level++ : 0)};
var result = proto[method].apply(this, [].slice.call(arguments, 1));
this[parentName].level--;
if (!this[parentName].level)
delete this[parentName];
return result;
}
};
console.log('--------- Point ---------\n');
// Point class
var Point = Object.create(Class, {
initialize: {value: function (x, y) {
console.log('Point.initialize', x, y);
this.move(x, y);
}},
move: {value: function (x, y) {
console.log('Point.move', x, y);
this.x = x;
this.y = y;
}},
toString: {value: function () {
return 'point: '.concat(this.x, ' ', this.y);
}},
name: {value: "Point"}
});
var p = Point.new(10, 20);
console.log(p); // <point 10 20>
console.log('\n--------- Point3D ---------\n');
var Point3D = Object.create(Point, {
initialize: {value: function (x, y, z) {
this.super('initialize', x, y);
this.z = z;
console.log('Point3D.initialize', x, y, z);
}},
move: {value: function (x, y, z) {
this.super('move', x, y);
this.z = z;
}},
toString: {value: function () {
return '3D ' + this.super('toString') + ' ' + this.z;
}},
name: {value: "Point3D"}
});
var p3D = Point3D.new(10, 20, 30);
console.log(p3D);
console.log('\n--------- Point4D ---------\n');
var Point4D = Object.create(Point3D, {
initialize: {value: function (x, y, z, time) {
this.super('initialize', x, y, z);
this.time = time;
console.log('Point4D.initialize', x, y, z, time);
}},
move: {value: function (x, y, z, time) {
this.super('move', x, y, z);
this.time = time;
}},
toString: {value: function () {
return '4D is ' + this.super('toString') + ' + ' + this.time;
}},
name: {value: "Point4D"}
});
var p4D = Point4D.new(10, 20, 30, 2011);
console.log(p4D);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment