Skip to content

Instantly share code, notes, and snippets.

@jbr
Forked from raganwald/multiple-dispatch.js
Last active August 29, 2015 14:02
Show Gist options
  • Save jbr/9f3bbc7c9a4db18ce88f to your computer and use it in GitHub Desktop.
Save jbr/9f3bbc7c9a4db18ce88f to your computer and use it in GitHub Desktop.
function isType (type) {
return function (arg) {
return typeof(arg) === type;
};
}
function instanceOf (clazz) {
return function (arg) {
return arg instanceof clazz;
};
}
function isPrototypeOf (proto) {
return Object.prototype.isPrototypeOf.bind(proto);
}
function check () {
var matchers = [].slice.call(arguments, 0, arguments.length - 1),
body = arguments[arguments.length - 1];
return function () {
var i,
arg,
value;
if (arguments.length != matchers.length) return;
for (i in arguments) {
arg = arguments[i];
if (!matchers[i].call(this, arg)) return;
}
value = body.apply(this, arguments);
return value === undefined
? null
: value;
}
}
function appendable (fns) {
var i,
value,
fn;
if (fns === undefined) fns = [];
function firstSuccess () {
for (i in fns) {
value = fns[i].apply(this, arguments);
if (value !== undefined) return value;
}
}
firstSuccess.appendChecked = function () {
return appendable(fns.concat([check.apply(this, arguments)]));
}
return firstSuccess;
}
function MultipleDispatch () {
return appendable().appendChecked.apply(this, arguments);
}
////////// EXAMPLE //////////
function Fighter () {};
function Meteor () {};
var handlesManyCases = MultipleDispatch(
instanceOf(Fighter), instanceOf(Meteor),
function (fighter, meteor) {
return "a fighter has hit a meteor";
}
).appendChecked(
instanceOf(Fighter), instanceOf(Fighter),
function (fighter, fighter) {
return "a fighter has hit another fighter";
}
).appendChecked(
instanceOf(Meteor), instanceOf(Fighter),
function (meteor, fighter) {
return "a meteor has hit a fighter";
}
).appendChecked(
instanceOf(Meteor), instanceOf(Meteor),
function (meteor, meteor) {
return "a meteor has hit another meteor";
}
);
handlesManyCases(new Meteor(), new Meteor());
//=> 'a meteor has hit another meteor'
handlesManyCases(new Fighter(), new Meteor());
//=> 'a fighter has hit a meteor'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment