Skip to content

Commit 0476d52

Browse files
committed
util: pass through the inspect function to custom inspect functions
This allows to use more portable custom inspect functions. Fixes: #35956 Signed-off-by: Ruben Bridgewater <[email protected]>
1 parent 265a47d commit 0476d52

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

doc/api/util.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ changes:
576576
codes. Colors are customizable. See [Customizing `util.inspect` colors][].
577577
**Default:** `false`.
578578
* `customInspect` {boolean} If `false`,
579-
`[util.inspect.custom](depth, opts)` functions are not invoked.
579+
`[util.inspect.custom](depth, opts, inspect)` functions are not invoked.
580580
**Default:** `true`.
581581
* `showProxy` {boolean} If `true`, `Proxy` inspection includes
582582
the [`target` and `handler`][] objects. **Default:** `false`.
@@ -854,9 +854,9 @@ ignored, if not supported.
854854
<!-- type=misc -->
855855

856856
Objects may also define their own
857-
[`[util.inspect.custom](depth, opts)`][util.inspect.custom] function,
857+
[`[util.inspect.custom](depth, opts, inspect)`][util.inspect.custom] function,
858858
which `util.inspect()` will invoke and use the result of when inspecting
859-
the object:
859+
the object.
860860

861861
```js
862862
const util = require('util');
@@ -866,7 +866,7 @@ class Box {
866866
this.value = value;
867867
}
868868

869-
[util.inspect.custom](depth, options) {
869+
[util.inspect.custom](depth, options, inspect) {
870870
if (depth < 0) {
871871
return options.stylize('[Box]', 'special');
872872
}
@@ -877,8 +877,8 @@ class Box {
877877

878878
// Five space padding because that's the size of "Box< ".
879879
const padding = ' '.repeat(5);
880-
const inner = util.inspect(this.value, newOptions)
881-
.replace(/\n/g, `\n${padding}`);
880+
const inner = inspect(this.value, newOptions)
881+
.replace(/\n/g, `\n${padding}`);
882882
return `${options.stylize('Box', 'special')}< ${inner} >`;
883883
}
884884
}
@@ -889,9 +889,9 @@ util.inspect(box);
889889
// Returns: "Box< true >"
890890
```
891891

892-
Custom `[util.inspect.custom](depth, opts)` functions typically return a string
893-
but may return a value of any type that will be formatted accordingly by
894-
`util.inspect()`.
892+
Custom `[util.inspect.custom](depth, opts, inspect)` functions typically return
893+
a string but may return a value of any type that will be formatted accordingly
894+
by `util.inspect()`.
895895

896896
```js
897897
const util = require('util');
@@ -921,8 +921,13 @@ In addition to being accessible through `util.inspect.custom`, this
921921
symbol is [registered globally][global symbol registry] and can be
922922
accessed in any environment as `Symbol.for('nodejs.util.inspect.custom')`.
923923

924+
Using this allows code to be written in a portable fashion, so that the custom
925+
inspect function is used in an Node.js environment and ignored in the browser.
926+
The `util.inspect()` function itself is passed as third argument to the custom
927+
inspect function to allow further portability.
928+
924929
```js
925-
const inspect = Symbol.for('nodejs.util.inspect.custom');
930+
const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom');
926931

927932
class Password {
928933
constructor(value) {
@@ -933,7 +938,7 @@ class Password {
933938
return 'xxxxxxxx';
934939
}
935940

936-
[inspect]() {
941+
[customInspectSymbol](depth, inspectOptions, inspect) {
937942
return `Password <${this.toString()}>`;
938943
}
939944
}

lib/internal/util/inspect.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,12 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
761761
const isCrossContext =
762762
proxy !== undefined || !(context instanceof Object);
763763
const ret = FunctionPrototypeCall(
764-
maybeCustom, context, depth, getUserOptions(ctx, isCrossContext));
764+
maybeCustom,
765+
context,
766+
depth,
767+
getUserOptions(ctx, isCrossContext),
768+
inspect
769+
);
765770
// If the custom inspection method returned `this`, don't go into
766771
// infinite recursion.
767772
if (ret !== context) {
@@ -1126,7 +1131,7 @@ function getClassBase(value, constructor, tag) {
11261131

11271132
function getFunctionBase(value, constructor, tag) {
11281133
const stringified = FunctionPrototypeToString(value);
1129-
if (stringified.slice(0, 5) === 'class' && stringified.endsWith('}')) {
1134+
if (stringified.startsWith('class') && stringified.endsWith('}')) {
11301135
const slice = stringified.slice(5, -1);
11311136
const bracketIndex = slice.indexOf('{');
11321137
if (bracketIndex !== -1 &&

test/parallel/test-util-inspect.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ util.inspect({ hasOwnProperty: null });
932932

933933
assert.strictEqual(util.inspect(subject), "{ foo: 'bar' }");
934934

935-
subject[util.inspect.custom] = common.mustCall((depth, opts) => {
935+
subject[util.inspect.custom] = common.mustCall((depth, opts, inspect) => {
936936
const clone = { ...opts };
937937
// This might change at some point but for now we keep the stylize function.
938938
// The function should either be documented or an alternative should be
@@ -942,12 +942,13 @@ util.inspect({ hasOwnProperty: null });
942942
assert.strictEqual(opts.budget, undefined);
943943
assert.strictEqual(opts.indentationLvl, undefined);
944944
assert.strictEqual(opts.showHidden, false);
945+
assert.strictEqual(inspect, util.inspect);
945946
assert.deepStrictEqual(
946-
new Set(Object.keys(util.inspect.defaultOptions).concat(['stylize'])),
947+
new Set(Object.keys(inspect.defaultOptions).concat(['stylize'])),
947948
new Set(Object.keys(opts))
948949
);
949950
opts.showHidden = true;
950-
return { [util.inspect.custom]: common.mustCall((depth, opts2) => {
951+
return { [inspect.custom]: common.mustCall((depth, opts2) => {
951952
assert.deepStrictEqual(clone, opts2);
952953
}) };
953954
});

0 commit comments

Comments
 (0)