Skip to content

Instantly share code, notes, and snippets.

@appden
Created April 23, 2009 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save appden/100694 to your computer and use it in GitHub Desktop.
Save appden/100694 to your computer and use it in GitHub Desktop.
Class.Initializers = {};
Class.Mutators.initialize = function(initialize){
return function(){
this._init_ = initialize;
for (var modifier in Class.Initializers) {
if (!this[modifier]) continue;
this[modifier] = Class.Initializers[modifier].call(this, this[modifier]);
}
return this._init_.apply(this, arguments);
};
};
Class.Initializers.Singleton = function(){
var init = this._init_;
this._init_ = function(){
var instance = init.apply(this, arguments) || this;
this.constructor.prototype.initialize = function(){
return instance;
};
return instance;
};
};
Class.Initializers.Binds = function(binds){
if (binds === true) {
for (var name in this) {
if (this[name]._origin && name != 'initialize' && name != '_current')
this[name] = this[name].bind(this);
}
} else {
$splat(binds).each(function(name){
var original = this[name];
if (original) this[name] = original.bind(this);
}, this);
}
};
// privates
Class.Initializers.Privates = function(privates){
var Private = function(){};
Private.prototype = this;
var internal = new Private; // internal inherits public properties
internal.Public = this;
// bind a method to the private object
var publicize = function(original){
return function(){
var result = original.apply(internal, arguments);
// return public object instead of internal if called from outside
return (result == internal && internal.caller == null) ? internal.Public : result;
};
};
// copy private properies into internal
for (var name in privates){
var item = privates[name];
internal[name] = ($type(item) == 'function') ? item.bind(internal) : $unlink(item);
}
// bind public methods to internal object
for (var name in this){
if (this[name]._origin && name != 'initialize' && name != '_current')
this[name] = publicize(this[name]);
}
};
// getters and setters
Class.Mutators.Getters = function(secrets){
secrets = $splat(secrets);
this.implement('get', function(prop){
if (!secrets.contains(prop)) return null;
var getter = this['get' + prop.capitalize()];
return (getter) ? getter.call(this) : this[prop];
});
};
Class.Mutators.Setters = function(secrets){
secrets = $splat(secrets);
this.implement('set', function(prop, value){
switch ($type(prop)){
case 'object':
for (var p in prop) this.set(p, prop[p]);
break;
case 'string':
if (secrets.contains(prop)){
var setter = this['set' + prop.capitalize()];
if (setter) setter.call(this, value);
else this[prop] = value;
}
}
return this;
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment