Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util: use a shared symbol for util.inspect.custom #20857

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,9 +569,10 @@ terminals.

<!-- type=misc -->

Objects may also define their own `[util.inspect.custom](depth, opts)` function
that `util.inspect()` will invoke and use the result of when inspecting the
object:
Objects may also define their own
[`[util.inspect.custom](depth, opts)`][util.inspect.custom] function,
which `util.inspect()` will invoke and use the result of when inspecting
the object:

```js
const util = require('util');
Expand Down Expand Up @@ -623,10 +624,41 @@ util.inspect(obj);
### util.inspect.custom
<!-- YAML
added: v6.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/20857
description: This is now defined as a shared symbol.
-->

* {symbol} that can be used to declare custom inspect functions, see
[Custom inspection functions on Objects][].
* {symbol} that can be used to declare custom inspect functions.

In addition to being accessible through `util.inspect.custom`, this
symbol is [registered globally][global symbol registry] and can be
accessed in any environment as `Symbol.for('nodejs.util.inspect.custom')`.

```js
const inspect = Symbol.for('nodejs.util.inspect.custom');

class Password {
constructor(value) {
this.value = value;
}

toString() {
return 'xxxxxxxx';
}

[inspect]() {
return `Password <${this.toString()}>`;
}
}

const password = new Password('r0sebud');
console.log(password);
// Prints Password <xxxxxxxx>
Copy link
Contributor

@vsemozhetbyt vsemozhetbyt May 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe // Prints "Password <xxxxxxxx>". ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would have been my preference, but most other Prints comments don't do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, maybe this unification is a task for some other PR)

```

See [Custom inspection functions on Objects][] for more details.

### util.inspect.defaultOptions
<!-- YAML
Expand Down Expand Up @@ -2071,7 +2103,6 @@ Deprecated predecessor of `console.log`.
[`Array.isArray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
[`ArrayBuffer.isView()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView
[async function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
[`assert.deepStrictEqual()`]: assert.html#assert_assert_deepstrictequal_actual_expected_message
[`Buffer.isBuffer()`]: buffer.html#buffer_class_method_buffer_isbuffer_obj
[`console.error()`]: console.html#console_console_error_data_args
Expand Down Expand Up @@ -2113,6 +2144,9 @@ Deprecated predecessor of `console.log`.
[Module Namespace Object]: https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects
[WHATWG Encoding Standard]: https://encoding.spec.whatwg.org/
[Common System Errors]: errors.html#errors_common_system_errors
[async function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
[constructor]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
[global symbol registry]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for
[list of deprecated APIS]: deprecations.html#deprecations_list_of_deprecated_apis
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
[util.inspect.custom]: #util_util_inspect_custom
2 changes: 1 addition & 1 deletion lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ module.exports = {

// Symbol used to provide a custom inspect function for an object as an
// alternative to using 'inspect'
customInspectSymbol: Symbol('util.inspect.custom'),
customInspectSymbol: Symbol.for('nodejs.util.inspect.custom'),

// Used by the buffer module to capture an internal reference to the
// default isEncoding implementation, just in case userland overrides it.
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ assert.throws(
'+ {}\n' +
'- {\n' +
"- loop: 'forever',\n" +
'- [Symbol(util.inspect.custom)]: [Function]\n' +
'- [Symbol(nodejs.util.inspect.custom)]: [Function]\n' +
'- }'
});

Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-console.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ for (const expected of expectedStrings) {
}

assert.strictEqual(strings.shift(),
"{ foo: 'bar',\n [Symbol(util.inspect.custom)]: " +
'[Function: [util.inspect.custom]] }\n');
"{ foo: 'bar',\n [Symbol(nodejs.util.inspect.custom)]: " +
'[Function: [nodejs.util.inspect.custom]] }\n');
assert.strictEqual(strings.shift(),
"{ foo: 'bar',\n [Symbol(util.inspect.custom)]: " +
'[Function: [util.inspect.custom]] }\n');
"{ foo: 'bar',\n [Symbol(nodejs.util.inspect.custom)]: " +
'[Function: [nodejs.util.inspect.custom]] }\n');
assert.ok(strings.shift().includes('foo: [Object]'));
assert.strictEqual(strings.shift().includes('baz'), false);
assert.strictEqual(strings.shift(), 'inspect inspect\n');
Expand Down
20 changes: 17 additions & 3 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ assert.strictEqual(util.inspect(Object.create(Date.prototype)), 'Date {}');
{
const x = { [util.inspect.custom]: util.inspect };
assert(util.inspect(x).includes(
'[Symbol(util.inspect.custom)]:\n { [Function: inspect]'));
'[Symbol(nodejs.util.inspect.custom)]:\n { [Function: inspect]'));
}

// `util.inspect` should display the escaped value of a key.
Expand Down Expand Up @@ -758,12 +758,26 @@ util.inspect({ hasOwnProperty: null });
};

util.inspect(subject, { customInspectOptions: true });

// util.inspect.custom is a shared symbol which can be accessed as
// Symbol.for("nodejs.util.inspect.custom").
const inspect = Symbol.for('nodejs.util.inspect.custom');

subject[inspect] = () => ({ baz: 'quux' });

assert.strictEqual(util.inspect(subject), '{ baz: \'quux\' }');

subject[inspect] = (depth, opts) => {
assert.strictEqual(opts.customInspectOptions, true);
};

util.inspect(subject, { customInspectOptions: true });
}

{
// Returning `this` from a custom inspection function works.
const subject = { a: 123, [util.inspect.custom]() { return this; } };
const UIC = 'util.inspect.custom';
const UIC = 'nodejs.util.inspect.custom';
assert.strictEqual(util.inspect(subject),
`{ a: 123,\n [Symbol(${UIC})]: [Function: [${UIC}]] }`);
}
Expand Down Expand Up @@ -1188,7 +1202,7 @@ util.inspect(process);
const obj = { [util.inspect.custom]: 'fhqwhgads' };
assert.strictEqual(
util.inspect(obj),
"{ [Symbol(util.inspect.custom)]: 'fhqwhgads' }"
"{ [Symbol(nodejs.util.inspect.custom)]: 'fhqwhgads' }"
);
}

Expand Down