Skip to content

Instantly share code, notes, and snippets.

@jboulhous
Created April 8, 2013 10:44
Show Gist options
  • Save jboulhous/5335884 to your computer and use it in GitHub Desktop.
Save jboulhous/5335884 to your computer and use it in GitHub Desktop.
a try to get some functional helpers from allong.es most of this code is copied from from https://github.com/raganwald/allong.es
// a try to get some functional helpers from allong.es
// most of this code is copied from from https://github.com/raganwald/allong.es
// helpers
var slice = Array.prototype.slice;
// to_function
function to_function (str) {
var expr, leftSection, params, rightSection, sections, v, vars, _i, _len;
params = [];
expr = str;
sections = expr.split(/\s*->\s*/m);
if (sections.length > 1) {
while (sections.length) {
expr = sections.pop();
params = sections.pop().split(/\s*,\s*|\s+/m);
sections.length && sections.push('(function(' + params + '){return (' + expr + ')})');
}
} else if (expr.match(/\b_\b/)) {
params = '_';
} else {
leftSection = expr.match(/^\s*(?:[+*\/%&|\^\.=<>]|!=)/m);
rightSection = expr.match(/[+\-*\/%&|\^\.=<>!]\s*$/m);
if (leftSection || rightSection) {
if (leftSection) {
params.push('$1');
expr = '$1' + expr;
}
if (rightSection) {
params.push('$2');
expr = expr + '$2';
}
} else {
vars = str.replace(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*\s*:|this|arguments|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g, '').match(/([a-z_$][a-z_$\d]*)/gi) || [];
for (_i = 0, _len = vars.length; _i < _len; _i++) {
v = vars[_i];
params.indexOf(v) >= 0 || params.push(v);
}
}
}
return new Function(params, 'return (' + expr + ')');
};
// functionalize
function functionalize (fn) {
if (typeof fn === 'function') {
return fn;
} else if (typeof fn === 'string' && /^[_a-zA-Z]\w*$/.test(fn)) {
return function() {
var args, receiver, _ref;
receiver = arguments[0];
args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
return (_ref = receiver[fn]).call.apply(_ref, [receiver].concat(slice.call(args)));
};
} else if (typeof fn === 'string') {
return to_function(fn);
} else if (typeof fn.lambda === 'function') {
return fn.lambda();
} else if (typeof fn.toFunction === 'function') {
return fn.toFunction();
}
}
// extend
function extend () {
var consumer = arguments[0],
providers = slice.call(arguments, 1),
key,
i,
provider,
except;
for (i = 0; i < providers.length; ++i) {
provider = providers[i];
except = provider['except'] || [];
except.push('except');
for (key in provider) {
if (except.indexOf(key) < 0 && provider.hasOwnProperty(key)) {
consumer[key] = provider[key];
}
}
}
return consumer;
}
/*
function Todo (name) {
var self = this instanceof Todo ? this : new Todo();
self.name = name || 'Untitled';
self.done = false;
};
Todo.prototype.do = fluent( function () { this.done = true; });
Todo.prototype.undo = fluent( function () { this.done = false; });
*/
function fluent (fn) {
fn = functionalize(fn);
return function () {
fn.apply(this, arguments);
return this
}
}
/*
var AddLocation = mixin({
setLocation: fluent( function (location) {
this.location = location;
}),
getLocation: function () { return this.location; }
});
AddLocation.call(Todo.prototype);
// Or use AddLocation(Todo.prototype)
new Todo("Vacuum").setLocation('Home');
//=> { name: 'Vacuum',
// done: false,
// location: 'Home' }
*/
function mixin (decoration) {
return function decorator () {
if (arguments[0] !== void 0) {
return decorator.call(arguments[0]);
}
else {
extend(this, decoration);
return this;
}
};
};
/*
var AndColourCoded = classDecorator({
setColourRGB: fluent( function (r, g, b) {
this.colourCode = { r: r, g: g, b: b };
}),
getColourRGB: function () {
return this.colourCode;
}
});
var ColourTodo = AndColourCoded(Todo);
new ColourTodo('Use More Decorators').setColourRGB(0, 255, 0);
*/
function classDecorator (decoration) {
return function (clazz) {
function Decorated () {
var self = this instanceof Decorated ? this : new Decorated();
return clazz.apply(self, arguments);
}
Decorated.prototype = extend(new clazz(), decoration);
return Decorated;
}
}
function Model (attr) {
var self = this instanceof Model ? this : new Model();
self.attr = attr || {};
if(_.isFunction(this.initialize))
this.initialize(attr);
};
var TodoIt = classDecorator({
constructor : function(attr){
this.attr = attr || {done:false};
},
do: function () {
this.attr.done = true ;
},
undo: function () {
this.attr.done = false ;
},
status : function () {
return this.attr.done;
}
});
var Todo = TodoIt(Model)
todo = new Todo({done:false})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment