util: allow symbol-based custom inspection methods · nodejs/node@59714cb · GitHub
Skip to content

Commit 59714cb

Browse files
committed
util: allow symbol-based custom inspection methods
Add a `util.inspect.custom` Symbol which can be used to customize `util.inspect()` output. Providing `obj[util.inspect.custom]` works like providing `obj.inspect`, except that the former allows avoiding name clashes with other `inspect()` methods. Fixes: #8071 PR-URL: #8174 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <mic.besace@gmail.com>
1 parent 6e50fc7 commit 59714cb

5 files changed

Lines changed: 108 additions & 21 deletions

File tree

doc/api/util.md

Lines changed: 31 additions & 6 deletions

lib/buffer.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,8 @@ Buffer.prototype.equals = function equals(b) {
500500
};
501501

502502

503-
// Inspect
504-
Buffer.prototype.inspect = function inspect() {
503+
// Override how buffers are presented by util.inspect().
504+
Buffer.prototype[internalUtil.inspectSymbol] = function inspect() {
505505
var str = '';
506506
var max = exports.INSPECT_MAX_BYTES;
507507
if (this.length > 0) {
@@ -511,6 +511,7 @@ Buffer.prototype.inspect = function inspect() {
511511
}
512512
return '<' + this.constructor.name + ' ' + str + '>';
513513
};
514+
Buffer.prototype.inspect = Buffer.prototype[internalUtil.inspectSymbol];
514515

515516
Buffer.prototype.compare = function compare(target,
516517
start,

lib/internal/util.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ const kDecoratedPrivateSymbolIndex = binding['decorated_private_symbol'];
99
exports.getHiddenValue = binding.getHiddenValue;
1010
exports.setHiddenValue = binding.setHiddenValue;
1111

12+
// The `buffer` module uses this. Defining it here instead of in the public
13+
// `util` module makes it accessible without having to `require('util')` there.
14+
exports.customInspectSymbol = Symbol('util.inspect.custom');
15+
1216
// All the internal deprecations have to use this function only, as this will
1317
// prepend the prefix to the actual message.
1418
exports.deprecate = function(fn, msg) {

lib/util.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ inspect.styles = {
242242
'regexp': 'red'
243243
};
244244

245+
const customInspectSymbol = internalUtil.customInspectSymbol;
246+
245247
exports.inspect = inspect;
248+
exports.inspect.custom = customInspectSymbol;
246249

247250
function stylizeWithColor(str, styleType) {
248251
var style = inspect.styles[styleType];
@@ -350,18 +353,20 @@ function formatValue(ctx, value, recurseTimes) {
350353

351354
// Provide a hook for user-specified inspect functions.
352355
// Check that value is an object with an inspect function on it
353-
if (ctx.customInspect &&
354-
value &&
355-
typeof value.inspect === 'function' &&
356-
// Filter out the util module, it's inspect function is special
357-
value.inspect !== exports.inspect &&
358-
// Also filter out any prototype objects using the circular check.
359-
!(value.constructor && value.constructor.prototype === value)) {
360-
var ret = value.inspect(recurseTimes, ctx);
361-
if (typeof ret !== 'string') {
362-
ret = formatValue(ctx, ret, recurseTimes);
356+
if (ctx.customInspect && value) {
357+
const maybeCustomInspect = value[customInspectSymbol] || value.inspect;
358+
359+
if (typeof maybeCustomInspect === 'function' &&
360+
// Filter out the util module, its inspect function is special
361+
maybeCustomInspect !== exports.inspect &&
362+
// Also filter out any prototype objects using the circular check.
363+
!(value.constructor && value.constructor.prototype === value)) {
364+
let ret = maybeCustomInspect.call(value, recurseTimes, ctx);
365+
if (typeof ret !== 'string') {
366+
ret = formatValue(ctx, ret, recurseTimes);
367+
}
368+
return ret;
363369
}
364-
return ret;
365370
}
366371

367372
// Primitive types cannot have properties

test/parallel/test-util-inspect.js

Lines changed: 54 additions & 2 deletions

0 commit comments

Comments
 (0)