pachinko
v0.0.1
Published
Multi pipe promises!
Downloads
1
Readme
Pachinko—Multi channel promise!
Downloads – Documentation – API – Integrating – Performance
Why another promise library?
....
Downloads
Tested to work against Internet Explorer 6+, Safari 3+, Google Chrome 1+, Firefox 3+, and Opera 10+!
Development Version (1.0.0) — 6.5 KiB, uncompressed with comments.
Production Version (1.0.0) — 715 bytes, minified and gzipped.
Documentation
Inheritance
...
API
Module
var Class = Self(definition)
var Class = Self.extend(definition)
Creates a new class. Self()
is shorthand for Self.extend()
.
var Class = Self(prototype, definition)
Shorthand for Self.extend(Self.create(prototype), definition)
.
var Class = Self.create(prototype)
Wraps a prototypal constructor as a Self class, returning the created class.
Self.VERSION
Property indicating the version of Self.
Class static methods & properties
var inst = Class(args...)
Calling returns an instance of the class, passing any arguments to the
constructor
method.
var Child = Class.extend(definition)
Extends the class with a new class definition, returning the created class.
Class.staticProps(definition) === Class
Sugar method for defining static properties on a class.
Class.mixin(AnotherClass) === Class
Copies another class's definitions into the current class.
Class.__super__
Parent class
Instance properties
inst.__class__
The class that created this instance.
inst.__super__
The parent class of this instance, same as inst.__class__.__super__
.
Integrating With Other Forms of OOP
Prototypal OOP
A prototype can be manually wrapped with Self.create
.
var EventEmitter = Self.create(require('events').EventEmitter);
Or use the shorthand and pass your base prototype as the first parameter in your class definition.
var Foobar = Self(EventEmitter, {
constructor: function (self) {
Foobar.__super__.constructor.call(self); // Calls EventEmitter's constructor
}
});
Backbone
Backbone's initialize
function is not the constructor. It's a
call super method, which gets called
by the real constructor. So as long as you keep the constructor semantics the
same, you'll be fine!
var MyModel = Self(Backbone.Model, {
initialize: function (self, attr, opts) {
MyModel.__super__.initialize.call(self, attr, opts);
}
});
I recommend extending the Backbone library into your own namespace, so you don't have to call Self on the library everytime. It also provides a place for you to roll your own base class logic.
var mvc = _.reduce(Backbone, function (obj, value, key) {
obj[key] = (value.prototype && _.keys(value.prototype).length) ? Self.create(value) : value;
return obj;
}, {});
mvc.Collection = mvc.Collection.extend({
});
Performance
Since Self.js wraps every method with a function that unshifts the context onto
your method's arguments, there is overhead. You will have to weigh the
performance impact vs the convenience of an explicit self
variable.
For me, an empty Self method is 2 orders of magnitude slower than an empty prototypal method. Keep in mind this overhead may be negligible compared to the time it takes to run the code in your method. Below are the actual timings of calling those methods on my machine.
- Without Self — 6 nanoseconds/call
- With Self — 610 nanoseconds/call
To run these benchmarks yourself, clone this project and run:
npm install -d && node ./benchmarks.js
Thoughts
It should be possible to macro Self methods in-place (only in Node.js), thus removing the overhead of wrapping every method. If anyone is interested in this, please let me know and we can investigate it!