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: add inspect.defaultOptions #8013

Closed
wants to merge 1 commit into from

Conversation

silverwind
Copy link
Contributor

Checklist
  • make -j4 test (UNIX), or vcbuild test nosign (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

util

Description of change

Adds the util.inspect.config() method to allow customization of inspect options in cases where util.inspect() is implicitly called by core like in console or util.format.

Fixes: #7566

@silverwind silverwind added util Issues and PRs related to the built-in util module. semver-minor PRs that contain new features and should be released in the next minor version. labels Aug 8, 2016
@@ -207,6 +207,23 @@ Values may supply their own custom `inspect(depth, opts)` functions, when
called these receive the current `depth` in the recursive inspection, as well as
the options object passed to `util.inspect()`.

### util.inspect.config([options])
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps a defaultOptions setter/getter would be better here? Something like...

util.inspect.defaultOptions = options;

// or even...

util.inspect.defaultOptions.maxArrayLength = 1000;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, seems cleaner.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I think it might be possible to make them plain properties. Would save some time having to compute the getter/setter names at least.

@jasnell
Copy link
Member

jasnell commented Aug 8, 2016

I'm generally +1 on having this, but prefer making it a getter/setter rather than a method.

return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;

inspect.config = function (options = {}) {
if (typeof options !== 'object') {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this check for null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, null is an issue. How about a strict object check instead?

if (Object.prototype.toString.call(options) === '[object Object]') {

Copy link
Contributor

Choose a reason for hiding this comment

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

In other places in core, I believe we've just been doing options === null || typeof options !== 'object'

@silverwind
Copy link
Contributor Author

Thanks for review. What's the general consensus on util._extend vs Object.assign? Shall we use the former in performance-critical paths, otherwise the latter?

@cjihrig
Copy link
Contributor

cjihrig commented Aug 8, 2016

Last I heard, we were still preferring util._extend() for performance reasons. However, I believe Object.assign() is more flexible, so it might be preferable in cases that would require multiple calls to util._extend().

@jbergstroem
Copy link
Member

Windows fail looks unrelated (Jenkins -- connection aborted)

@silverwind
Copy link
Contributor Author

silverwind commented Aug 8, 2016

Also, not sure what's up with the linter on CI:

+ gmake lint-ci
./node tools/jslint.js -j 1 -f tap -o test-eslint.tap \
    benchmark lib src test tools
gmake: *** [Makefile:677: jslint-ci] Error 1

Definitely passes locally.

@silverwind
Copy link
Contributor Author

Nevermind, there's some lint errors. Fixing them.

@silverwind
Copy link
Contributor Author

silverwind commented Aug 8, 2016

Updated to use the util.inspect.defaultOptions property instead of a function.

  • I sealed the object to prevent addition/deletion of options.
  • Currently, the property is writable: false to prevent shenanigans like defaultOptions = null which would break inspect. The downside of this is that we can't set using a object, just through individual properties, one at a time. Thoughts about writeable, @jasnell?

@jasnell
Copy link
Member

jasnell commented Aug 8, 2016

Using a getter/setter would help protect against things like defaultOptions = null, just have the setter function check to see if the input is valid and ignore it if it is not.

I'm not convinced that sealing the object is necessary but it's likely harmless.

@silverwind
Copy link
Contributor Author

@jasnell Sealing for example prevents delete defaultOptions.depth for of the current solution without accessors.

Supporting both defaultOptions = {} and defaultOptions.property = true through getters/setters would introduce quite a big amount of code. I'm not sure if it's really that common to set all properties at once. In my case, I'd only like to change depth and maxArrayLength.

@silverwind
Copy link
Contributor Author

silverwind commented Aug 8, 2016

@jasnell I've switched to accessors now. The solution turned out shorter than I thought and should satisfy all cases. I'd like to keep the properties sealed to prevent some misuse like deleting, and so I can Object.assign without checking for property existance in the setter.

@silverwind
Copy link
Contributor Author

@silverwind silverwind changed the title util: add inspect.config util: add inspect.defaultOptions Aug 8, 2016
set to an object containing one or more valid [`util.inspect()`][] options.
Setting properties directly is also supported.

Returns the current options as an object.
Copy link
Member

Choose a reason for hiding this comment

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

s/options/default options

@jasnell
Copy link
Member

jasnell commented Aug 8, 2016

LGTM with a nit if CI is green.

const arr = Array(101);
const oldOptions = Object.assign({}, util.inspect.defaultOptions);

// set single properties
Copy link
Contributor

Choose a reason for hiding this comment

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

Tiny nit, but could you capitalize "set" here and in the comment below.

@cjihrig
Copy link
Contributor

cjihrig commented Aug 8, 2016

LGTM pending CI.

@silverwind
Copy link
Contributor Author

CI is green except a hanging Windows box. Giving this PR a bit of time for others to weight in.

@@ -215,7 +215,7 @@ by `util.inspect`. This is useful for functions like `console.log` or
set to an object containing one or more valid [`util.inspect()`][] options.
Setting properties directly is also supported.

Returns the current options as an object.
Returns the current default options as an object.
Copy link
Member

@Trott Trott Aug 8, 2016

Choose a reason for hiding this comment

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

Since this is a property and not a function, it doesn't really "return" anything, right? It just is a value. I'd be inclined to delete the line entirely. I don't think it actually adds any information. (I also think it's misleading. If you don't set it, it's undefined and not an object.)

Copy link
Member

Choose a reason for hiding this comment

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

(Whoops, the parenthetical is wrong, ignore it. Also, uh, yeah, looks like I'm commenting on an out-of-date diff. SMH. Sorry.)

@evanlucas
Copy link
Contributor

LGTM with Trott's nit fixed

@silverwind
Copy link
Contributor Author

Nit addressed. One more CI: https://ci.nodejs.org/job/node-test-pull-request/3589/

@jasnell
Copy link
Member

jasnell commented Aug 9, 2016

still LGTM :-)

@silverwind
Copy link
Contributor Author

silverwind commented Aug 9, 2016

Noticed a bug where the REPL module called to inspect using the legacy form with undefined properties:

util.inspect(obj, undefined, undefined, true)

The undefined properties were overriding the defaults in the Object.assign call. I fixed the issue by not adding undefined props to ctx and added a test for it. Also made it copy opts last, so it matches previous behaviour.

One last CI:

https://ci.nodejs.org/job/node-test-pull-request/3598/
https://ci.nodejs.org/job/node-test-pull-request/3599/
https://ci.nodejs.org/job/node-test-pull-request/3600/

@jasnell
Copy link
Member

jasnell commented Aug 9, 2016

oh, good catch @silverwind

Adds util.inspect.defaultOptions which allows customization of the
default util.inspect options, which is useful for functions like
console.log or util.format which implicitly call into util.inspect.

PR-URL: nodejs#8013
Fixes: nodejs#7566
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Evan Lucas <[email protected]>
silverwind added a commit that referenced this pull request Aug 9, 2016
Adds util.inspect.defaultOptions which allows customization of the
default util.inspect options, which is useful for functions like
console.log or util.format which implicitly call into util.inspect.

PR-URL: #8013
Fixes: #7566
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Evan Lucas <[email protected]>
@silverwind
Copy link
Contributor Author

silverwind commented Aug 9, 2016

One unrelated CI failure on Windows. Landed in d9ef3e1 1a6a69a.

@silverwind silverwind closed this Aug 9, 2016
silverwind added a commit that referenced this pull request Aug 9, 2016
Adds util.inspect.defaultOptions which allows customization of the
default util.inspect options, which is useful for functions like
console.log or util.format which implicitly call into util.inspect.

PR-URL: #8013
Fixes: #7566
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Evan Lucas <[email protected]>
@silverwind
Copy link
Contributor Author

There was a silly typo in the error message. I --force-with-lease pushed 1a6a69a to correct it.

@cjihrig cjihrig mentioned this pull request Aug 10, 2016
cjihrig pushed a commit that referenced this pull request Aug 10, 2016
Adds util.inspect.defaultOptions which allows customization of the
default util.inspect options, which is useful for functions like
console.log or util.format which implicitly call into util.inspect.

PR-URL: #8013
Fixes: #7566
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Evan Lucas <[email protected]>
@cjihrig cjihrig mentioned this pull request Aug 11, 2016
cjihrig added a commit that referenced this pull request Aug 11, 2016
Notable changes:

* build: zlib symbols and additional OpenSSL symbols are now exposed on Windows platforms. (Alex Hultman) #7983 and #7576
* child_process, cluster: Forked child processes and cluster workers now support stdio configuration. (Colin Ihrig) #7811 and #7838
* fs: fs.ReadStream now exposes the number of bytes it has read so far. (Linus Unnebäck) #7942
* repl: The REPL now supports editor mode. (Prince J Wesley) #7275
* util: inspect() can now be configured globally using util.inspect.defaultOptions. (Roman Reiss) #8013

Refs: #8020
PR-URL: #8070
cjihrig added a commit that referenced this pull request Aug 11, 2016
Notable changes:

* build: zlib symbols and additional OpenSSL symbols are now exposed on Windows platforms. (Alex Hultman) #7983 and #7576
* child_process, cluster: Forked child processes and cluster workers now support stdio configuration. (Colin Ihrig) #7811 and #7838
* child_process: argv[0] can now be set to arbitrary values in spawned processes. (Pat Pannuto) #7696
* fs: fs.ReadStream now exposes the number of bytes it has read so far. (Linus Unnebäck) #7942
* repl: The REPL now supports editor mode. (Prince J Wesley) #7275
* util: inspect() can now be configured globally using util.inspect.defaultOptions. (Roman Reiss) #8013

Refs: #8020
PR-URL: #8070
cjihrig added a commit that referenced this pull request Aug 15, 2016
Notable changes:

* build: zlib symbols and additional OpenSSL symbols are now exposed on Windows platforms. (Alex Hultman) #7983 and #7576
* child_process, cluster: Forked child processes and cluster workers now support stdio configuration. (Colin Ihrig) #7811 and #7838
* child_process: argv[0] can now be set to arbitrary values in spawned processes. (Pat Pannuto) #7696
* fs: fs.ReadStream now exposes the number of bytes it has read so far. (Linus Unnebäck) #7942
* repl: The REPL now supports editor mode. (Prince J Wesley) #7275
* util: inspect() can now be configured globally using util.inspect.defaultOptions. (Roman Reiss) #8013

Refs: #8020
PR-URL: #8070
cjihrig added a commit to cjihrig/node that referenced this pull request Aug 16, 2016
Notable changes:

* build: zlib symbols and additional OpenSSL symbols are now exposed on Windows platforms. (Alex Hultman) nodejs#7983 and nodejs#7576
* child_process, cluster: Forked child processes and cluster workers now support stdio configuration. (Colin Ihrig) nodejs#7811 and nodejs#7838
* child_process: argv[0] can now be set to arbitrary values in spawned processes. (Pat Pannuto) nodejs#7696
* fs: fs.ReadStream now exposes the number of bytes it has read so far. (Linus Unnebäck) nodejs#7942
* repl: The REPL now supports editor mode. (Prince J Wesley) nodejs#7275
* util: inspect() can now be configured globally using util.inspect.defaultOptions. (Roman Reiss) nodejs#8013

Refs: nodejs#8020
PR-URL: nodejs#8070
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-minor PRs that contain new features and should be released in the next minor version. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants