is there a way to detect if a method call in a chain (fluent interface) is in TAIL position in that chain ?
var some = g.f(arg1).f(arg2).f(arg3);
or do we absolutely need something like
var some = g.f(arg1).f(arg2).f(arg3).end();
which I want avoid ?
REturned value is not so important for me, but I need to compute something (an internal string-like key) at the end of the chain, with could have different lengths from one call to another.
No, there is no way to detect if a given method is in the tail position if the function call looks identical because the next chained invocation has not yet happened and the interpreter doesn't offer you any evidence for whether there is another chained invocation coming or not.
You could make an optional second argument that was the clue you are looking for:
var some = g.f(arg1).f(arg2).f(arg3, "end");
Then, your f()
function would just check to see if the second argument was present and had the appropriate value and, if so, it could carry out the tail operations.
Or, you could make a slightly different version of f()
called fTail()
(or whatever you want to call it):
var some = g.f(arg1).f(arg2).fTail(arg3);
fTail()
could look like this:
xxx.prototype.fTail = function() {
var retVal = this.f.apply(this, arguments);
// now do your tail operations here
return retVal;
};
As you have proposed, I think I'd go with an array of args since that seems to solve all your issues, is easy to use and will perform well:
var some = g.f([arg1, arg2, arg3], fn);