AncientSwordRage
AncientSwordRage

Reputation: 7608

How can I determine what arguments have already been passed to a lodash partial function?

Let say I'm passing different data into a function in different places to work around some legacy decisions/code.

var partialFunction;
if(thisSituationIsCrazy(data, value)) {
    partialFunction = _.partial(originalFunciton, data)
} else {
    partialFunction = _.partialRight(originalFunction, value)
}

Is there a way to determine what values were actually passed in and at which place in the function? This is only for debugging purposes.

I'm hoping for something like partialFunction.arguments or some such that would shed some light on where it's gotten to, because the actual situation is more complicated than my example.

I've not seen a way to do it based on the lodash docs, nor on the source code. I've also not seen this mentioned in any blogs on the subject.

Upvotes: 4

Views: 214

Answers (2)

Bamieh
Bamieh

Reputation: 10906

There is a concept of Higher order functions (HOF) in functional programming, which proves very powerful for this case.

HOF is a function that wraps another function, while it adds "extra hands" to the passed function.

//now a demo of what you want
function greet(a, b, c) {
  return a + ' ' + b + ' ' + c;
}

function trackArguments(fn, ctx) {
  const trackedArgs = [];
  function tracker(partialFn, ...args) {
     trackedArgs.push(...args);
     const res = fn.call(ctx, partialFn, ...args);
     res.trackedArgs = trackedArgs;
     return res;
  }
  tracker.trackedArgs = trackedArgs;
  return tracker
}
 
const trackedPartial = trackArguments(_.partial, _);

var sayHelloTo = trackedPartial(greet, 'hello', 'Stack');

console.log('Arguments passed already:', sayHelloTo.trackedArgs);

console.log('Execution works perfctly:', sayHelloTo('Overflow'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Upvotes: 1

Koushik Chatterjee
Koushik Chatterjee

Reputation: 4175

Obviously that is implemented inside the function, and when you invoke the final callback, its access the actual function from closer, and that is not exposed.

However if you want that really, you can go ahead and wrap that for your purpose:

//your wrapping inside a IIFE (Immediately-Invoked Function Expression)
(function() {
    var _partial = _.partial,
        _partialRight = _.partialRight;
    _.partial = function() {
        var args = Array.from(arguments).slice(1),
            ret = _partial.apply(_, arguments);
        ret.args = args;
        return ret;
    }

    _.partialRight = function() {
        var args = Array.from(arguments).slice(1),
            ret = _partialRight.apply(_, arguments);
        ret.args = args;
        return ret;
    }
})();

//now a demo of what you want
function greet(a, b, c) {
  return a + ' ' + b + ' ' + c;
}
 
var sayHelloTo = _.partial(greet, 'hello', 'Stack');
console.log('Arguments passed already:', sayHelloTo.args);
console.log('Execution works perfctly:', sayHelloTo('Overflow'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Upvotes: 1

Related Questions