foop
Version:
interfaces that describe their intentions.
80 lines (76 loc) • 7.71 kB
JavaScript
var argumentor = require('../cast/argumentor')
var slice = require('../native/arraySlice')
var isNill = require('../is/nullOrUndefined')
var isFunction = require('../is/function')
var hasIn = require('../is/hasIn')
var curry = require('./curry')
/**
* @desc simple desc:
* - pass in numberOfArgs & methodName
* - when the function is called, with 1 more arg than the number of args you gave
* it uses that as
* // arguments 0-numberOfArgs...
* `leftover = arguments.slice(0, numberOfArgs)`
* `target[numberOfArgs][methodName](leftover)`
* longer desc:
* - Turns a named method with a specified arity into a function that can be
* called directly supplied with arguments and a target object.
* - The returned function is curried and accepts `arity + 1` parameters where
* the final parameter is the target object.
*
* @since 5.0.0-beta.6
* @NOTE has safety and returns `undefined` when there is no method for the function
* @TODO add the `safety` to debugRecord
*
* @func
* @name invoker
* @memberOf fp
* @ramda v0.1.0
* @category Function
* @sig Number -> String -> (a -> b -> ... -> n -> Object -> *)
*
* @param {Number} arity Number of arguments the returned function should take
* before the target object.
* @param {String} method Name of the method to call.
* @return {Function} A new curried function.
*
* {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L294 underscore-invoke}
* {@link https://github.com/ramda/ramda/blob/master/src/invoker.js ramda-invoker}
* @see {@link underscore-invoker}
* @see {@link ramda-invoker}
* @see fp/construct
*
* @symb invoker(0, 'method')(o) = o['method']()
* @symb invoker(1, 'method')(a, o) = o['method'](a)
* @symb invoker(2, 'method')(a, b, o) = o['method'](a, b)
*
* @example
*
* const sliceFrom = invoker(1, 'slice');
* sliceFrom(6, 'abcdefghijklm'); //=> 'ghijklm'
*
* const sliceFrom6 = invoker(2, 'slice')(6);
* sliceFrom6(8, 'abcdefghijklm'); //=> 'gh'
*
*/
module.exports = curry(2, function invoker(arity, method) {
return curry(arity + 1, function() {
var args = argumentor.apply(null, arguments)
var target = args[arity]
// !isNill(target) && isFunction(target[method])
// if (hasIn(target, method)) {
if (hasIn(target, method) && isFunction(target[method])) {
return target[method]
.apply(
target
.apply(target, args
.slice(0, arity))
)
}
else {
return undefined
}
// throw new TypeError(toString(target) + ' does not have a method named "' + method + '"')
})
})
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2tlci5qcyIsInNvdXJjZXMiOlsiaW52b2tlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBhcmd1bWVudG9yID0gcmVxdWlyZSgnLi4vY2FzdC9hcmd1bWVudG9yJylcbmNvbnN0IHNsaWNlID0gcmVxdWlyZSgnLi4vbmF0aXZlL2FycmF5U2xpY2UnKVxuY29uc3QgaXNOaWxsID0gcmVxdWlyZSgnLi4vaXMvbnVsbE9yVW5kZWZpbmVkJylcbmNvbnN0IGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pcy9mdW5jdGlvbicpXG5jb25zdCBoYXNJbiA9IHJlcXVpcmUoJy4uL2lzL2hhc0luJylcbmNvbnN0IGN1cnJ5ID0gcmVxdWlyZSgnLi9jdXJyeScpXG5cbi8qKlxuICogQGRlc2Mgc2ltcGxlIGRlc2M6XG4gKiAgIC0gcGFzcyBpbiBudW1iZXJPZkFyZ3MgJiBtZXRob2ROYW1lXG4gKiAgIC0gd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLCB3aXRoIDEgbW9yZSBhcmcgdGhhbiB0aGUgbnVtYmVyIG9mIGFyZ3MgeW91IGdhdmVcbiAqICAgICBpdCB1c2VzIHRoYXQgYXNcbiAqICAgICAgICAvLyBhcmd1bWVudHMgMC1udW1iZXJPZkFyZ3MuLi5cbiAqICAgICAgICBgbGVmdG92ZXIgPSBhcmd1bWVudHMuc2xpY2UoMCwgbnVtYmVyT2ZBcmdzKWBcbiAqICAgICAgICBgdGFyZ2V0W251bWJlck9mQXJnc11bbWV0aG9kTmFtZV0obGVmdG92ZXIpYFxuICogICBsb25nZXIgZGVzYzpcbiAqICAgLSBUdXJucyBhIG5hbWVkIG1ldGhvZCB3aXRoIGEgc3BlY2lmaWVkIGFyaXR5IGludG8gYSBmdW5jdGlvbiB0aGF0IGNhbiBiZVxuICogICAgIGNhbGxlZCBkaXJlY3RseSBzdXBwbGllZCB3aXRoIGFyZ3VtZW50cyBhbmQgYSB0YXJnZXQgb2JqZWN0LlxuICogICAtIFRoZSByZXR1cm5lZCBmdW5jdGlvbiBpcyBjdXJyaWVkIGFuZCBhY2NlcHRzIGBhcml0eSArIDFgIHBhcmFtZXRlcnMgd2hlcmVcbiAqICAgICB0aGUgZmluYWwgcGFyYW1ldGVyIGlzIHRoZSB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBzaW5jZSA1LjAuMC1iZXRhLjZcbiAqIEBOT1RFIGhhcyBzYWZldHkgYW5kIHJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSBpcyBubyBtZXRob2QgZm9yIHRoZSBmdW5jdGlvblxuICogQFRPRE8gYWRkIHRoZSBgc2FmZXR5YCB0byBkZWJ1Z1JlY29yZFxuICpcbiAqIEBmdW5jXG4gKiBAbmFtZSBpbnZva2VyXG4gKiBAbWVtYmVyT2YgZnBcbiAqIEByYW1kYSB2MC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHNpZyBOdW1iZXIgLT4gU3RyaW5nIC0+IChhIC0+IGIgLT4gLi4uIC0+IG4gLT4gT2JqZWN0IC0+ICopXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGFyaXR5IE51bWJlciBvZiBhcmd1bWVudHMgdGhlIHJldHVybmVkIGZ1bmN0aW9uIHNob3VsZCB0YWtlXG4gKiAgICAgICAgYmVmb3JlIHRoZSB0YXJnZXQgb2JqZWN0LlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCBOYW1lIG9mIHRoZSBtZXRob2QgdG8gY2FsbC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIG5ldyBjdXJyaWVkIGZ1bmN0aW9uLlxuICpcbiAqIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vamFzaGtlbmFzL3VuZGVyc2NvcmUvYmxvYi9tYXN0ZXIvdW5kZXJzY29yZS5qcyNMMjk0IHVuZGVyc2NvcmUtaW52b2tlfVxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9yYW1kYS9yYW1kYS9ibG9iL21hc3Rlci9zcmMvaW52b2tlci5qcyByYW1kYS1pbnZva2VyfVxuICogQHNlZSB7QGxpbmsgdW5kZXJzY29yZS1pbnZva2VyfVxuICogQHNlZSB7QGxpbmsgcmFtZGEtaW52b2tlcn1cbiAqIEBzZWUgZnAvY29uc3RydWN0XG4gKlxuICogQHN5bWIgaW52b2tlcigwLCAnbWV0aG9kJykobykgPSBvWydtZXRob2QnXSgpXG4gKiBAc3ltYiBpbnZva2VyKDEsICdtZXRob2QnKShhLCBvKSA9IG9bJ21ldGhvZCddKGEpXG4gKiBAc3ltYiBpbnZva2VyKDIsICdtZXRob2QnKShhLCBiLCBvKSA9IG9bJ21ldGhvZCddKGEsIGIpXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgIGNvbnN0IHNsaWNlRnJvbSA9IGludm9rZXIoMSwgJ3NsaWNlJyk7XG4gKiAgICAgIHNsaWNlRnJvbSg2LCAnYWJjZGVmZ2hpamtsbScpOyAvLz0+ICdnaGlqa2xtJ1xuICpcbiAqICAgICAgY29uc3Qgc2xpY2VGcm9tNiA9IGludm9rZXIoMiwgJ3NsaWNlJykoNik7XG4gKiAgICAgIHNsaWNlRnJvbTYoOCwgJ2FiY2RlZmdoaWprbG0nKTsgLy89PiAnZ2gnXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGN1cnJ5KDIsIGZ1bmN0aW9uIGludm9rZXIoYXJpdHksIG1ldGhvZCkge1xuICByZXR1cm4gY3VycnkoYXJpdHkgKyAxLCBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBhcmdzID0gYXJndW1lbnRvci5hcHBseShudWxsLCBhcmd1bWVudHMpXG4gICAgY29uc3QgdGFyZ2V0ID0gYXJnc1thcml0eV1cblxuICAgIC8vICFpc05pbGwodGFyZ2V0KSAmJiBpc0Z1bmN0aW9uKHRhcmdldFttZXRob2RdKVxuICAgIC8vIGlmIChoYXNJbih0YXJnZXQsIG1ldGhvZCkpIHtcbiAgICBpZiAoaGFzSW4odGFyZ2V0LCBtZXRob2QpICYmIGlzRnVuY3Rpb24odGFyZ2V0W21ldGhvZF0pKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0W21ldGhvZF1cbiAgICAgICAgLmFwcGx5KFxuICAgICAgICAgIHRhcmdldFxuICAgICAgICAgICAgLmFwcGx5KHRhcmdldCwgYXJnc1xuICAgICAgICAgICAgICAuc2xpY2UoMCwgYXJpdHkpKVxuICAgICAgICApXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIC8vIHRocm93IG5ldyBUeXBlRXJyb3IodG9TdHJpbmcodGFyZ2V0KSArICcgZG9lcyBub3QgaGF2ZSBhIG1ldGhvZCBuYW1lZCBcIicgKyBtZXRob2QgKyAnXCInKVxuICB9KVxufSlcbiJdLCJuYW1lcyI6WyJjb25zdCJdLCJtYXBwaW5ncyI6IkFBQUFBLEdBQUssQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDO0FBQ2hEQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQztBQUM3Q0EsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUM7QUFDL0NBLEdBQUssQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzVDQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7QUFDcENBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbURoQyxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRTtFQUN4RCxPQUFPLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLFdBQVc7SUFDakNBLEdBQUssQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDO0lBQzlDQSxHQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7Ozs7SUFJMUIsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtNQUN2RCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDbEIsS0FBSztVQUNKLE1BQU07YUFDSCxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUk7ZUFDaEIsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUN0QjtLQUNKO1NBQ0k7TUFDSCxPQUFPLFNBQVM7S0FDakI7OztHQUdGLENBQUM7Q0FDSCxDQUFDOyJ9