Skip to content

Instantly share code, notes, and snippets.

@jcmoore
Created May 7, 2014 07:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcmoore/55397f09ca701a65cccd to your computer and use it in GitHub Desktop.
Save jcmoore/55397f09ca701a65cccd to your computer and use it in GitHub Desktop.
loco.js -- reusable, chainable, multiple, return values
var Loco = (function LocoMake () {
var nadda = {},
empty = {}
caboose = null,
Railcar = function Railcar () {
this.value = nadda;
this.deref = this;
};
Railcar.prototype.ended = function ended () {
return this.value === empty;
};
Railcar.prototype.motive = function motive () {
return this.deref.value;
};
Railcar.prototype.couple = function couple () {
var count = arguments.length,
index = 0,
before = this,
after = null,
temp = null;
for (index = 0; index < count; index++) {
after = arguments[index];
temp = after.deref;
after.deref = before.deref;
before.deref = temp;
before = after;
}
return after;
};
Railcar.prototype.motion = function motion (skip) {
var deref = null,
result = this;
skip = (skip === void 0) ? 0 : skip;
do {
if (this.ended()) {
result = null;
break;
}
deref = this.deref;
this.deref = deref.deref;
deref.repool();
} while (skip === null || skip-- > 0);
return result;
};
Railcar.prototype.derail = function derail (skip) {
var deref = this.deref,
result = deref.value;
skip = (skip === void 0) ? 0 : skip;
do {
deref = this.deref;
result = deref.value;
if (!this.motion(0) ||
result === nadda) {
result = null;
}
} while (skip === null || skip-- > 0);
return result;
};
Railcar.prototype.repool = function repool () {
if (this.value !== empty) {
this.value = empty;
this.deref = caboose;
caboose = this;
}
};
var unpool = function unpool () {
var result = null;
if (caboose) {
result = caboose;
result.value = nadda;
result.deref = result;
caboose = caboose.deref;
} else {
result = new Railcar();
}
return result;
};
return function Loco () {
var count = arguments.length,
index = 0,
before = null,
after = null,
first = null;
if (count) {
first = after = before = unpool();
before.value = arguments[0];
for (index = 1; index < count; index++) {
after = unpool();
after.value = arguments[index];
before.deref = after;
before = after;
}
before.deref = first;
}
return before;
};
}) ();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment