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

Discuss supporting a %j formatting specifier? #81

Open
Fishrock123 opened this issue Dec 19, 2016 · 12 comments
Open

Discuss supporting a %j formatting specifier? #81

Fishrock123 opened this issue Dec 19, 2016 · 12 comments

Comments

@Fishrock123
Copy link

Fishrock123 commented Dec 19, 2016

In Node.js, a %j formatting specifier runs JSON.stringify() on the related arg. I am unsure what checks it makes other than '[Circular]', but I can take a look.

Example:

$ node
> console.log('JSON: %j', { greeting: 'hello!' })
JSON: {"greeting":"hello!"}

More information can be found in our docs on util.format(format[, ...args]) (Effectively our equivalent of the spec's Format function.)

@terinjokes
Copy link
Collaborator

This seems similar to how a non-interactive console might implement %O.

%O Element is displayed as an expanded JavaScript object; potentially interactive

@domenic
Copy link
Member

domenic commented Dec 19, 2016

Given that this is in only one of the five implementations, it seems best for Node.js to remove it, so that people can write interoperable code using %O or %o, instead of code that only works in Node.js using %j.

@Fishrock123
Copy link
Author

Possibly. Does anyone think printing JSON as a formatter is useful?

@JosephPecoraro
Copy link

I filed an issue that we should do this in Safari / WebKit a while back. It would not be hard to implement and seems reasonable to me.

@domenic
Copy link
Member

domenic commented Dec 20, 2016

It sounds like it's more complicated than just JSON.stringify unfortunately, so until Node manages to put together a spec for their behavior, I would hold off on creating a second divergent implementation.

@Fishrock123
Copy link
Author

I don't suggest following us unless we decide it is useful / a good idea.


These are the relative code bits for %j in Node.js:

https://github.com/nodejs/node/blob/7b924f1713006219e20ae7f011405d18b3ac7426/lib/util.js#L95-L102 & https://github.com/nodejs/node/blob/7b924f1713006219e20ae7f011405d18b3ac7426/lib/util.js#L60-L66

Which are really quite simple:

// Within "Format"
1      // f = string to be formatted
2      // i = index of the % character
3      switch (f.charCodeAt(i + 1)) {
4        case 106: // The 'j' character
5          // a = argument index to be inserted
6          if (a >= argLen)
7            break;
8          // lastPos = previous i, + 2 (0 at the start)
9          // str = the formatted string to return
10         if (lastPos < i)
11           str += f.slice(lastPos, i);
12         str += tryStringify(arguments[a++]);
13         lastPos = i = i + 2;
14         continue;
//


15 function tryStringify(arg) {
16   try {
17    return JSON.stringify(arg);
18  } catch (_) {
19    return '[Circular]';
20  }
21 }

My spec language isn't good but that case could be maybe summed up as:

  • (3) If the specifier is j ...
  • (6 - 7) Check that there is a value to be inserted.
  • (10 - 11) Get the string up until this formatting specifier.
  • (12 ...) Attempt to stringify the next value from args via tryStringify().
    • (16 - 17) Try to JSON.stringify() and return it.
    • (18 - 19) If there is an error in the previous step, return '[Circular]'.
  • (... 12) Append the stringified next value to string from (10 - 11).
  • (13) Prepare for the next formating specifier.

@Fishrock123 Fishrock123 changed the title Support a %j formatting specifier Discuss supporting a %j formatting specifier? Dec 20, 2016
@rocketpan
Copy link

The spec says

%O Element is displayed as an expanded JavaScript object; potentially interactive

Why not just alias %j to %O and spec out non-interactive object? two birds one stone

@domenic
Copy link
Member

domenic commented Dec 20, 2016

An important thing to consider in standardization discussions is the concept of the shortest path to interop. If Node simply removes %j, we have achieved interop. Whereas if we try to get the four other consoles to implement it, we don't achieve interop for a much longer time (maybe never, since so far we have interest only from WebKit), and we increase the likelihood of people writing code that only works in some environments in the meantime.

So, that's why aliasing %j to %O is not a super-great option. It would move us from a simple short path to interop that the current spec provides (only one console needs to change), to a very long one (involving changes to all 5 consoles).

@Fishrock123
Copy link
Author

An important thing to consider in standardization discussions is the concept of the shortest path to interop. If Node simply removes %j, we have achieved interop.

Removing features from platforms is pretty painful compared to adding features, unfortunately. :/

We can spec out what exists in most common first but I think this discussion is still valuable to be had since we've had it for a long time AFAIK.

@Fishrock123
Copy link
Author

Why not just alias %j to %O and spec out non-interactive object? two birds one stone

I think it's more of a question if anyone finds the JSON output useful enough to perhaps have that as an option in browsers to.

I'm personally not sure how useful it is, but idk maybe someone can think of a better use than myself.

@refack
Copy link

refack commented Aug 5, 2017

Hello guy, newcomer here. I'm not here to argue, and I'm only bringing my POV.

An important thing to consider in standardization discussions is the concept of the shortest path to interop. If Node simply removes %j, we have achieved interop.

@domenic I believe that statement could be improved if you add the idea of pain to it, as in shortest and least painful path to interop.
I'm a big believer in standardization, but IMHO it's hard to achieve if it requires breaking existing user's code or experiences.
Also (and I'm sure it was mentioned before) it's not as simple as to say node is 1/5 implementations, since it's 1/1 server side implementations, and is 1/1 non interactive implementations.

@domenic
Copy link
Member

domenic commented Aug 5, 2017

Sure, these are all reasonable points. On the other hand, if one implementation goes out and adds something without a standard in place to support it, it's pretty unlikely that other implementations will follow along, and it's a bad precedent to set. We've done it sometimes (especially in the IE6 days), but in general we prefer a more collaborative working mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants