Description
Affected URL(s)
https://nodejs.org/docs/latest/api/util.html#utildebuglogsection-callback
Description of the problem
The usage example of the callback function for util.debuglog
is not sufficiently documented imho.
Moreover, when looking at the code, it also seems to even work differently than described.
The example for the callback does the following:
const util = require('node:util');
let debuglog = util.debuglog('internals', (debug) => {
// Replace with a logging function that optimizes out
// testing if the section is enabled
debuglog = debug;
});
What debuglog effectively does is:
function debuglog(set, cb){
realLogFunction = (...args){
init() //sets up the set name and an enabled boolean value
// creates a noop function when enabled=false
realLogFunction = debugLogImpl(enabled)
if(typeof cb == "function"){
// this is the part where the documentation is lacking
cb(realLogFunction) //code depends on side-effects of the callback?
}
// this line is only effective the very first time, when still in the factory
// likely to not 'swallow' the first log line that lazily inits the real logger
realLogFunction(...args)
}
//left out for brewity, but works on the same principle as realLogFunction
let innerEnabledCheck ()=>{...}
logDelegate = (...) => {
//some switch on argument length, but effectively always results in the next line, with a varying
//amount of arguments passed on.
realLogFunction(args)
}
logDelegate.enabled = innerEnabledCheck() //left out for brewity
return logDelegate;
}
The first time logDelegate
is called, the enabled test is already optimized out and logDelegate
will call the now-changed realLogFunction
generated from debugLogImpl
.
What actually happens when the callback is used as in the documentation's example, is that the outside variable, (debuglog
in the example) which points to logDelegate
, will be replaced by realLogFunction
.
Thus, what is 'optimized out' is the switch in logDelegate
when the callback is used as shown in the example, but at the price of also losing the enabled
getter. 'Testing if the section is enabled' is always automatically and implicitly optimized out in the inner factory method.