Skip to content

Instantly share code, notes, and snippets.

@gchudnov
Last active December 2, 2016 10:19
Show Gist options
  • Save gchudnov/77eb193ccd0789dbae6d to your computer and use it in GitHub Desktop.
Save gchudnov/77eb193ccd0789dbae6d to your computer and use it in GitHub Desktop.
function createMultimethod(dispatch, noMatch) {
if(typeof dispatch !== 'function') {
throw new TypeError('dispatch must be a function');
}
const dict = {};
if(typeof noMatch == 'function') {
dict.noMatch = noMatch;
}
return new Proxy(() => { throw new Error('No match'); }, {
set(target, property, value) {
dict[property] = value;
return true;
},
apply(target, thisArg, args) {
const value = dispatch.apply(null, args);
const func = (value && dict.hasOwnProperty(value)
? dict[value]
: (dict.hasOwnProperty('noMatch')
? dict['noMatch']
: target));
return func.apply(thisArg, args);
}
});
}
// Usage:
let dispatchFunc = person => person && person.manners;
let noMatchFunc = () => { return 3.0; };
let coffeePrice2 = createMultimethod(dispatchFunc, noMatchFunc);
coffeePrice2.polite = (person) => {
return 2.00;
};
coffeePrice2.rude = (person) => {
return 6.00;
};
let alice = { name: 'Alice', manners: 'polite' };
let bob = { name: 'Bob', manners: 'rude' };
console.log('$' + coffeePrice2(alice)); // $2
console.log('$' + coffeePrice2(bob)); // $6
console.log('$' + coffeePrice2()); // $3
coffeePrice2.veryPolite = (person) => {
return 1.85;
};
let carol = { name: 'Carol', manners: 'veryPolite' };
console.log('$' + coffeePrice2(carol)); // $1.85
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment