-
Notifications
You must be signed in to change notification settings - Fork 30k
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
doc: added symbols guidelines #22684
Conversation
doc/guides/using-symbols.md
Outdated
} | ||
``` | ||
|
||
Local symbols makes it harder for developers to monkey patch/access |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/makes/make
801d47f
to
40ec16b
Compare
Tagging it tsc-agenda to raise awareness. cc @nodejs/tsc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the content could probably be replaced with a link to MDN, but LGTM. A link to MDN probably wouldn't hurt either way though 😄
doc/guides/using-symbols.md
Outdated
it is often used for metaprogramming purposes, as they can be used as | ||
property keys like string. There are two types of | ||
symbols, local and globals. Symbols are not included in | ||
JSON.stringify() but thay are by `util.inspect()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/thay/they/
doc/guides/using-symbols.md
Outdated
In the Node.js runtime we prefix all our global symbols with `nodejs.`, | ||
e.g. `Symbol.for('nodejs.hello')`. | ||
|
||
Globals symbols should be preferred to allow customizations of certain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Globals/Global/
I suggest to rephrase this sentence to something like: Global symbols are used in Node.js to allow customization of certain behaviors, i.e., metaprogramming.
doc/guides/using-symbols.md
Outdated
# Using global symbols | ||
|
||
ES6 introduced a new type: `Symbol`. This new type is _immutable_, and | ||
it is often used for metaprogramming purposes, as they can be used as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as they
is a bit confusing since there are no plurals before (except purposes
).
doc/guides/using-symbols.md
Outdated
ES6 introduced a new type: `Symbol`. This new type is _immutable_, and | ||
it is often used for metaprogramming purposes, as they can be used as | ||
property keys like string. There are two types of | ||
symbols, local and globals. Symbols are not included in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
globals
-> global
?
doc/guides/using-symbols.md
Outdated
private fields, as they require more work than a property prefixed | ||
with an `_`. | ||
|
||
## Global symbols - `Symbol.for` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Symbol.for
-> Symbol.for()
?
doc/guides/using-symbols.md
Outdated
ES6 introduced a new type: `Symbol`. This new type is _immutable_, and | ||
it is often used for metaprogramming purposes, as they can be used as | ||
property keys like string. There are two types of | ||
symbols, local and globals. Symbols are not included in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Symbols in the GlobalSymbolRegistry have no intrinsic differences from symbols created through Symbol()
-- other than that it is in a global map. There are no two "types" of symbols.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a user point of view, those are two different things. It might well be the same type, but a) I cannot add a symbol that I created to the global map and b) I cannot remove a symbol from the global map. Specifically Symbol('hello') !== Symbol('hello')
and Symbol.for('hello') === Symbol.for('hello')
: this alone makes me think that they are two different things. Would you mind to suggest some different wording?
doc/guides/using-symbols.md
Outdated
symbols, local and globals. Symbols are not included in | ||
JSON.stringify() but thay are by `util.inspect()`. | ||
|
||
## Local `Symbol` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no such thing as a "local" Symbol. Just say symbols created using the Symbol()
function.
doc/guides/using-symbols.md
Outdated
|
||
Local symbols make it harder for developers to monkey patch/access | ||
private fields, as they require more work than a property prefixed | ||
with an `_`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Say why this is good. If I were an unsuspecting developer I might consider
make it harder for developers to monkey patch/access private fields
a bad thing and question why Node.js is doing this.
doc/guides/using-symbols.md
Outdated
In the Node.js runtime we prefix all our global symbols with `nodejs.`, | ||
e.g. `Symbol.for('nodejs.hello')`. | ||
|
||
Globals symbols should be preferred to allow customizations of certain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive home the fact that the symbol is intended developer-facing.
Global symbols should be preferred when a developer-facing interface is needed to allow behavior customization, i.e., metaprogramming.
doc/guides/using-symbols.md
Outdated
## Global symbols - `Symbol.for` | ||
|
||
Global symbols are created with `Symbol.for(string)`. These symbols are | ||
stored in a global registry and they can be easily retrieved. However, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also clarify what "global" mean here: they are global to all contexts (including VM contexts) in the same process/JavaScript agent/V8 Isolate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would just say v8 isolate
doc/guides/using-symbols.md
Outdated
For this reason, we often use them to simulate private fields, like so: | ||
|
||
```js | ||
const kField = Symbol('field'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this Symbol('kField')
. Having consistent naming is so helpful for grep
-ping, and I’ve been changing it to this pattern whenever I touched these lines.
40ec16b
to
a9d210a
Compare
PTAL @TimothyGu @addaleax. |
doc/guides/using-symbols.md
Outdated
monkey-patchable make maintaining and evolving Node.js harder, as private | ||
properties are not documented and can change within a patch release. | ||
Some extremely popular modules in the ecosystem monkey patch some | ||
internals, making it impossible for us to update and imoprove those |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/imoprove/improve/
doc/guides/using-symbols.md
Outdated
properties are not documented and can change within a patch release. | ||
Some extremely popular modules in the ecosystem monkey patch some | ||
internals, making it impossible for us to update and imoprove those | ||
areas without breaking a significant amount of users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-breaking
+causing issues for
a9d210a
to
0d9162a
Compare
Landed in 4f5aa36. |
PR-URL: #22684 Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Vse Mozhet Byt <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]>
PR-URL: #22684 Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Vse Mozhet Byt <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]>
@BridgeAR suggested to make symbols non-enumerable for private fields in #22747 (comment). If we decide to do that, we should probably add to these guidelines, so I would love to hear opinions. |
I’m not super fond of that, because we would have to use defineProperty instead of a basic assignment in class definitions and in a lot of property assignment. It’d make the code less maintainable over time and it might cause some performance loss. |
I'm not particularly fond of it either. While I was not really happy with the change that caused symbols to be included in the inspect output, if we really want to hide those details we can do so by providing a custom inspect implementation. |
I don't think that the code becomes less maintainable by using A custom inspect function is not ideal since we would have to reimplement a couple of features every time and that's significantly more work and code than just switching to non-enumerable properties. |
The refactoring needed to https://github.com/nodejs/node/blob/master/lib/internal/http2/core.js would be massive, and definitely hinder its readability. As an example node/lib/internal/http2/core.js Lines 1566 to 1595 in 922a1b0
|
PR-URL: nodejs#22770 Refs: nodejs#22684 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
PR-URL: #22770 Refs: #22684 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
Define `util.inspect.custom` as `Symbol.for("nodejs.util.inspect.custom")` rather than `Symbol("util.inspect.custom")`. This allows `inspect` hooks to easily/safely be defined in non-Node.js environments. Fixes: #20821 Refs: #22684 PR-URL: #20857 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: John-David Dalton <[email protected]>
PR-URL: #22770 Refs: #22684 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
PR-URL: #22770 Refs: #22684 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
Define `util.inspect.custom` as `Symbol.for("nodejs.util.inspect.custom")` rather than `Symbol("util.inspect.custom")`. This allows `inspect` hooks to easily/safely be defined in non-Node.js environments. Fixes: nodejs#20821 Refs: nodejs#22684 PR-URL: nodejs#20857 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: John-David Dalton <[email protected]>
Define `util.inspect.custom` as `Symbol.for("nodejs.util.inspect.custom")` rather than `Symbol("util.inspect.custom")`. This allows `inspect` hooks to easily/safely be defined in non-Node.js environments. Fixes: #20821 Refs: #22684 Backport-PR-URL: #23039 PR-URL: #20857 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: John-David Dalton <[email protected]>
I've added the
Symbol
guideline that spun out from the discussion in #20857.Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes