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: deprecate obj.inspect for custom inspection #15631

Closed
wants to merge 2 commits into from

Conversation

Trott
Copy link
Member

@Trott Trott commented Sep 26, 2017

The existence of obj.inspect() for custom inspection can cause people
to unintentionally break console.log() and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

Refs: #15549

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

util

@nodejs-github-bot nodejs-github-bot added the doc Issues and PRs related to the documentations. label Sep 26, 2017
doc/api/util.md Outdated
@@ -377,8 +377,8 @@ terminals.
<!-- type=misc -->

Objects may also define their own `[util.inspect.custom](depth, opts)`
(or, equivalently `inspect(depth, opts)`) function that `util.inspect()` will
invoke and use the result of when inspecting the object:
(or, equivalently but deprecated, `inspect(depth, opts)`) function that
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure, but maybe "equivalent but deprecated"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, you're correct. Even better might be or the equivalent but deprecated which is what I'll switch it to in a minute.

@vsemozhetbyt vsemozhetbyt added the util Issues and PRs related to the built-in util module. label Sep 26, 2017
@addaleax
Copy link
Member

This is a documentation-only deprecation that can hopefully land in 8.x.

Just to give context, the alternative was only introduced a little more than a year ago in 6.4.0. I am perfectly fine with landing this in 8.x but I’d like to wait a little longer until we consider a runtime-deprecation.

@Trott Trott added the notable-change PRs with changes that should be highlighted in changelogs. label Sep 26, 2017
@Trott Trott added the semver-minor PRs that contain new features and should be released in the next minor version. label Sep 27, 2017
@Trott
Copy link
Member Author

Trott commented Sep 27, 2017

Labeling semver-minor as our docs indicate that is the minimum for a doc-only deprecation.

@evanlucas
Copy link
Contributor

can we check ecosystem usage of this before we land this?

@Trott
Copy link
Member Author

Trott commented Sep 28, 2017

can we check ecosystem usage of this before we land this?

@evanlucas The same question was asked in #15549 and @refack answered (in #15549 (comment)) like this:

@ChALkeR @refack would you be so kind and try finding out how often this might be used?

It's a tricky query to run... preliminary results indicate "no very often".

Compatibility risks are always there, but util.inspect will still give an output for objects after this change, just a less helpful one.

Just a reminder, deprecation is still far from removal (a full cycle needs at least two major versions). And even after a "full deprecation" removal is not automatic. So IMHO if it's a "bad" API that already has a better implementation, deciding to deprecate should be easier.

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

+1 as a docs-only deprecation

@refack
Copy link
Contributor

refack commented Sep 28, 2017

can we check ecosystem usage of this before we land this?

querying for /\binspect\b/ results in more than 50KLOCs. In a partial manual review, I only picked up Q - #15549 (comment)

@ljharb
Copy link
Member

ljharb commented Sep 29, 2017

Can someone confirm; will util.inspect fall back to the string "inspect" if util.inspect.custom is not available? Is there a plan in the future to change this behavior?

@jasnell
Copy link
Member

jasnell commented Sep 29, 2017

Yes, the string inspect will still work. This is a docs only deprecation for now. Which means no runtime changes at all


Using a property named `inspect` on an object to specify a custom inspection
function for [`util.inspect()`][] is deprecated. Use [`util.inspect.custom`][]
instead.
Copy link
Member

Choose a reason for hiding this comment

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

It might be helpful to note that, if compatibility is desired, having the method present under both names is always going to work?

Copy link
Member Author

Choose a reason for hiding this comment

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

I like the idea but I'm struggling with how to word it in a way that doesn't encourage people to use both if they're only using the Symbol. We don't want to create more messages if/when we move to a runtime deprecation. Suggestions welcome.

Copy link
Member

Choose a reason for hiding this comment

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

@Trott The thing is, even if we move to a runtime deprecation, the symbol property will be the first one that’s detected, and the string property ignored – so if both are present, the runtime deprecation won’t be emitted… or am I misunderstanding what you’re saying?

Copy link
Member Author

Choose a reason for hiding this comment

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

@addaleax Good point. I've added some text in a separate commit.

@refack
Copy link
Contributor

refack commented Sep 29, 2017

Can someone confirm; will util.inspect fall back to the string "inspect" if util.inspect.custom is not available? Is there a plan in the future to change this behavior?

AFAICT the long term "plan" is to runtime deprecate then remove, but that cycle requires at least two major versions, and future consensus.

The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

Refs: nodejs#15549
@@ -707,7 +707,8 @@ Type: Documentation-only

Using a property named `inspect` on an object to specify a custom inspection
function for [`util.inspect()`][] is deprecated. Use [`util.inspect.custom`][]
instead.
instead. (For backwards compatibility with Node.js prior to version 6.4.0, both
may be specified.)
Copy link
Member

Choose a reason for hiding this comment

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

instead (For backwards compatibility with Node.js prior to version 6.4.0, both may be specified). ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think since it's a whole sentence (not just a clause) inside the parentheses the period should be inside.
image
http://www.thepunctuationguide.com/parentheses.html

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps the parentheses are unnecessary anyway?

@BridgeAR
Copy link
Member

BridgeAR commented Oct 2, 2017

Landed in c09c04f

I removed the braces while landing.

@BridgeAR BridgeAR closed this Oct 2, 2017
BridgeAR pushed a commit that referenced this pull request Oct 2, 2017
The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

PR-URL: #15631
Refs: #15549
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorins
Copy link
Contributor

This does not land cleanly on 8.x. Could you please manually backport.

@MylesBorins
Copy link
Contributor

nvm I figured it out ☺️

MylesBorins pushed a commit that referenced this pull request Oct 3, 2017
The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

PR-URL: #15631
Refs: #15549
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Oct 3, 2017
MylesBorins pushed a commit that referenced this pull request Oct 3, 2017
The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

PR-URL: #15631
Refs: #15549
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
addaleax pushed a commit to addaleax/ayo that referenced this pull request Oct 4, 2017
The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

PR-URL: nodejs/node#15631
Refs: nodejs/node#15549
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this pull request Oct 11, 2017
The existence of `obj.inspect()` for custom inspection can cause people
to unintentionally break `console.log()` and friends. This is a
documentation-only deprecation that can hopefully land in 8.x.

PR-URL: #15631
Refs: #15549
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins added a commit that referenced this pull request Oct 11, 2017
Notable Changes:

* deps:
  * update npm to 5.4.2
    #15600
  * upgrade libuv to 1.15.0
    #15745
  * update V8 to 6.1.534.42
    #15393
* dgram:
  * support for setting dgram socket buffer size
    #13623
* fs:
  * add support O_DSYNC file open constant
    #15451
* util:
  * deprecate obj.inspect for custom inspection
    #15631
* tools, build:
  * there is a fancy new macOS installer
    #15179
* Added new collaborator
  * bmeurer - Benedikt Meurer - https://github.com/bmeurer
  * kfarnung - Kyle Farnung - https://github.com/kfarnung

PR-URL: #15762
MylesBorins added a commit that referenced this pull request Oct 11, 2017
Notable Changes:

* deps:
  * update npm to 5.4.2
    #15600
  * upgrade libuv to 1.15.0
    #15745
  * update V8 to 6.1.534.42
    #15393
* dgram:
  * support for setting dgram socket buffer size
    #13623
* fs:
  * add support O_DSYNC file open constant
    #15451
* util:
  * deprecate obj.inspect for custom inspection
    #15631
* tools, build:
  * there is a fancy new macOS installer
    #15179
* Added new collaborator
  * bmeurer - Benedikt Meurer - https://github.com/bmeurer
  * kfarnung - Kyle Farnung - https://github.com/kfarnung

PR-URL: #15762
addaleax pushed a commit to addaleax/ayo that referenced this pull request Oct 12, 2017
Notable Changes:

* deps:
  * update npm to 5.4.2
    nodejs/node#15600
  * upgrade libuv to 1.15.0
    nodejs/node#15745
  * update V8 to 6.1.534.42
    nodejs/node#15393
* dgram:
  * support for setting dgram socket buffer size
    nodejs/node#13623
* fs:
  * add support O_DSYNC file open constant
    nodejs/node#15451
* util:
  * deprecate obj.inspect for custom inspection
    nodejs/node#15631
* tools, build:
  * there is a fancy new macOS installer
    nodejs/node#15179
* Added new collaborator
  * bmeurer - Benedikt Meurer - https://github.com/bmeurer
  * kfarnung - Kyle Farnung - https://github.com/kfarnung

PR-URL: nodejs/node#15762
@vitaly-t
Copy link
Contributor

vitaly-t commented Oct 17, 2017

I saw the change, read documentation and played with the Node and the code, and still cannot quite get it...

In order to provide custom console output for each of my custom types I used to do this:

MyType.prototype.inspect = function(){
    return 'CUSTOM VALUE';
}

How am I to change this code for the latest Node.js?

@addaleax
Copy link
Member

@vitaly-t basically, whenever you want your custom inspect function and care about older Node versions, also do:

MyType.prototype.inspect = function(){
    return 'CUSTOM VALUE';
};
if (util.inspect.custom) {
  MyType.prototype[util.inspect.custom] = MyType.prototype.inspect;
}

If you do not care about Node < 6.4.0, you can (and probably should) just use

MyType.prototype[util.inspect.custom] = function(){
    return 'CUSTOM VALUE';
};

The reason for this is that it’s hard to tell for Node whether inspect was meant to be a custom inspection function for util.inspect, or somebody accidentally called it that way. With a symbol, that problem goes away.

@vitaly-t
Copy link
Contributor

vitaly-t commented Oct 18, 2017

@addaleax Thank you! But if this is the case, then why the first code below works fine, while the one after doesn't?

Works:

const obj = {
    inspect: () => {
        return 'INSPECT';
    }
};
console.log(obj);
//=> INSPECT

Doesn't work:

const obj = {
    util: {
        inspect: {
            custom: () => {
                return 'INSPECT';
            }
        }
    }
};
console.log(obj);
//=> { util: { inspect: { custom: [Function: custom] } } }

Node.js v8.7.0

@ljharb
Copy link
Member

ljharb commented Oct 18, 2017

@vitaly-t it's require('util').inspect.custom, eg:

const obj = {
  [require('util').inspect.custom]() {
    return 'INSPECT';
  }
};
console.log(obj);

@vitaly-t
Copy link
Contributor

vitaly-t commented Oct 18, 2017

@ljharb Ouch,... tricky! I think documentation needs to get better on this one 😄 Thank you!

Also, I'd like to figure out what that require('util').inspect.custom really returns. I can only see in the console for it saying Symbol(util.inspect.custom). Inspecting the inspection 😄

@addaleax
Copy link
Member

I think documentation needs to get better on this one 😄

PRs are definitely very welcome!

Also, I'd like to figure out what that require('util').inspect.custom really returns. I can only see in the console for it saying Symbol(util.inspect.custom)

I am not sure if this is helpful or not, but: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol (i.e. there isn’t really much more information contained in the value of util.inspect.custom than what Symbol(util.inspect.custom) says)

@gibfahn
Copy link
Member

gibfahn commented Jan 15, 2018

Release team were -1 on landing on v6.x, if you disagree let us know.

@ljharb
Copy link
Member

ljharb commented Jan 15, 2018

@gibfahn on landing the deprecation, the new symbol, or either?

@gibfahn
Copy link
Member

gibfahn commented Jan 15, 2018

@gibfahn on landing the deprecation, the new symbol, or either?

On landing the deprecation, though it wasn't a heavy -1, as with all backports we'd like to hear others' thoughts (we have a week to decide).

Which is the new symbol? I don't see it in this PR.

@ljharb
Copy link
Member

ljharb commented Jan 15, 2018

ah, you're right, it was added in #8174 (and backported to 4.x in #9688) and this is just the deprecation.

@tniessen tniessen added the deprecations Issues and PRs related to deprecations. label Sep 7, 2018
@Trott Trott deleted the address-15549 branch January 13, 2022 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecations Issues and PRs related to deprecations. doc Issues and PRs related to the documentations. notable-change PRs with changes that should be highlighted in changelogs. 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.

None yet