| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6f0ec98 commit 91df200
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -485,6 +485,9 @@ stream.write('With ES6'); | |||
| 485 | 485 | <!-- YAML | |
| 486 | 486 | added: v0.3.0 | |
| 487 | 487 | changes: | |
| 488 | + - version: REPLACEME | ||
| 489 | + pr-url: https://github.com/nodejs/node/pull/41003 | ||
| 490 | + description: The `numericSeparator` option is supported now. | ||
| 488 | 491 | - version: | |
| 489 | 492 | - v14.6.0 | |
| 490 | 493 | - v12.19.0 | |
@@ -606,6 +609,9 @@ changes: | |||
| 606 | 609 | set to `'set'`, only getters with a corresponding setter are inspected. | |
| 607 | 610 | This might cause side effects depending on the getter function. | |
| 608 | 611 | **Default:** `false`. | |
| 612 | + * `numericSeparator` {boolean} If set to `true`, an underscore is used to | ||
| 613 | + separate every three digits in all bigints and numbers. | ||
| 614 | + **Default:** `false`. | ||
| 609 | 615 | * Returns: {string} The representation of `object`. | |
| 610 | 616 | ||
| 611 | 617 | The `util.inspect()` method returns a string representation of `object` that is | |
@@ -754,6 +760,21 @@ assert.strict.equal( | |||
| 754 | 760 | ); | |
| 755 | 761 | ``` | |
| 756 | 762 | ||
| 763 | + The `numericSeparator` option adds an underscore every three digits to all | ||
| 764 | + numbers. | ||
| 765 | + | ||
| 766 | + ```js | ||
| 767 | + const { inspect } = require('util'); | ||
| 768 | + | ||
| 769 | + const thousand = 1_000; | ||
| 770 | + const million = 1_000_000; | ||
| 771 | + const bigNumber = 123_456_789n; | ||
| 772 | + const bigDecimal = 1_234.123_45; | ||
| 773 | + | ||
| 774 | + console.log(thousand, million, bigNumber, bigDecimal); | ||
| 775 | + // 1_000 1_000_000 123_456_789n 1_234.123_45 | ||
| 776 | + ``` | ||
| 777 | + | ||
| 757 | 778 | `util.inspect()` is a synchronous method intended for debugging. Its maximum | |
| 758 | 779 | output length is approximately 128 MB. Inputs that result in longer output will | |
| 759 | 780 | be truncated. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,7 +26,9 @@ const { | |||
| 26 | 26 | MathMin, | |
| 27 | 27 | MathRound, | |
| 28 | 28 | MathSqrt, | |
| 29 | + MathTrunc, | ||
| 29 | 30 | Number, | |
| 31 | + NumberIsFinite, | ||
| 30 | 32 | NumberIsNaN, | |
| 31 | 33 | NumberParseFloat, | |
| 32 | 34 | NumberParseInt, | |
@@ -168,7 +170,8 @@ const inspectDefaultOptions = ObjectSeal({ | |||
| 168 | 170 | breakLength: 80, | |
| 169 | 171 | compact: 3, | |
| 170 | 172 | sorted: false, | |
| 171 | - getters: false | ||
| 173 | + getters: false, | ||
| 174 | + numericSeparator: false, | ||
| 172 | 175 | }); | |
| 173 | 176 | ||
| 174 | 177 | const kObjectType = 0; | |
@@ -244,6 +247,7 @@ function getUserOptions(ctx, isCrossContext) { | |||
| 244 | 247 | compact: ctx.compact, | |
| 245 | 248 | sorted: ctx.sorted, | |
| 246 | 249 | getters: ctx.getters, | |
| 250 | + numericSeparator: ctx.numericSeparator, | ||
| 247 | 251 | ...ctx.userOptions | |
| 248 | 252 | }; | |
| 249 | 253 | ||
@@ -301,7 +305,8 @@ function inspect(value, opts) { | |||
| 301 | 305 | breakLength: inspectDefaultOptions.breakLength, | |
| 302 | 306 | compact: inspectDefaultOptions.compact, | |
| 303 | 307 | sorted: inspectDefaultOptions.sorted, | |
| 304 | - getters: inspectDefaultOptions.getters | ||
| 308 | + getters: inspectDefaultOptions.getters, | ||
| 309 | + numericSeparator: inspectDefaultOptions.numericSeparator, | ||
| 305 | 310 | }; | |
| 306 | 311 | if (arguments.length > 1) { | |
| 307 | 312 | // Legacy... | |
@@ -949,7 +954,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { | |||
| 949 | 954 | formatter = formatArrayBuffer; | |
| 950 | 955 | } else if (keys.length === 0 && protoProps === undefined) { | |
| 951 | 956 | return prefix + | |
| 952 | - `{ byteLength: ${formatNumber(ctx.stylize, value.byteLength)} }`; | ||
| 957 | + `{ byteLength: ${formatNumber(ctx.stylize, value.byteLength, false)} }`; | ||
| 953 | 958 | } | |
| 954 | 959 | braces[0] = `${prefix}{`; | |
| 955 | 960 | ArrayPrototypeUnshift(keys, 'byteLength'); | |
@@ -1434,13 +1439,61 @@ function handleMaxCallStackSize(ctx, err, constructorName, indentationLvl) { | |||
| 1434 | 1439 | assert.fail(err.stack); | |
| 1435 | 1440 | } | |
| 1436 | 1441 | ||
| 1437 | - function formatNumber(fn, value) { | ||
| 1438 | - // Format -0 as '-0'. Checking `value === -0` won't distinguish 0 from -0. | ||
| 1439 | - return fn(ObjectIs(value, -0) ? '-0' : `${value}`, 'number'); | ||
| 1442 | + function addNumericSeparator(integerString) { | ||
| 1443 | + let result = ''; | ||
| 1444 | + let i = integerString.length; | ||
| 1445 | + const start = integerString.startsWith('-') ? 1 : 0; | ||
| 1446 | + for (; i >= start + 4; i -= 3) { | ||
| 1447 | + result = `_${integerString.slice(i - 3, i)}${result}`; | ||
| 1448 | + } | ||
| 1449 | + return i === integerString.length ? | ||
| 1450 | + integerString : | ||
| 1451 | + `${integerString.slice(0, i)}${result}`; | ||
| 1452 | + } | ||
| 1453 | + | ||
| 1454 | + function addNumericSeparatorEnd(integerString) { | ||
| 1455 | + let result = ''; | ||
| 1456 | + let i = 0; | ||
| 1457 | + for (; i < integerString.length - 3; i += 3) { | ||
| 1458 | + result += `${integerString.slice(i, i + 3)}_`; | ||
| 1459 | + } | ||
| 1460 | + return i === 0 ? | ||
| 1461 | + integerString : | ||
| 1462 | + `${result}${integerString.slice(i)}`; | ||
| 1463 | + } | ||
| 1464 | + | ||
| 1465 | + function formatNumber(fn, number, numericSeparator) { | ||
| 1466 | + if (!numericSeparator) { | ||
| 1467 | + // Format -0 as '-0'. Checking `number === -0` won't distinguish 0 from -0. | ||
| 1468 | + if (ObjectIs(number, -0)) { | ||
| 1469 | + return fn('-0', 'number'); | ||
| 1470 | + } | ||
| 1471 | + return fn(`${number}`, 'number'); | ||
| 1472 | + } | ||
| 1473 | + const integer = MathTrunc(number); | ||
| 1474 | + const string = String(integer); | ||
| 1475 | + if (integer === number) { | ||
| 1476 | + if (!NumberIsFinite(number) || string.includes('e')) { | ||
| 1477 | + return fn(string, 'number'); | ||
| 1478 | + } | ||
| 1479 | + return fn(`${addNumericSeparator(string)}`, 'number'); | ||
| 1480 | + } | ||
| 1481 | + if (NumberIsNaN(number)) { | ||
| 1482 | + return fn(string, 'number'); | ||
| 1483 | + } | ||
| 1484 | + return fn(`${ | ||
| 1485 | + addNumericSeparator(string) | ||
| 1486 | + }.${ | ||
| 1487 | + addNumericSeparatorEnd(String(number).slice(string.length + 1)) | ||
| 1488 | + }`, 'number'); | ||
| 1440 | 1489 | } | |
| 1441 | 1490 | ||
| 1442 | - function formatBigInt(fn, value) { | ||
| 1443 | - return fn(`${value}n`, 'bigint'); | ||
| 1491 | + function formatBigInt(fn, bigint, numericSeparator) { | ||
| 1492 | + const string = String(bigint); | ||
| 1493 | + if (!numericSeparator) { | ||
| 1494 | + return fn(`${string}n`, 'bigint'); | ||
| 1495 | + } | ||
| 1496 | + return fn(`${addNumericSeparator(string)}n`, 'bigint'); | ||
| 1444 | 1497 | } | |
| 1445 | 1498 | ||
| 1446 | 1499 | function formatPrimitive(fn, value, ctx) { | |
@@ -1464,9 +1517,9 @@ function formatPrimitive(fn, value, ctx) { | |||
| 1464 | 1517 | return fn(strEscape(value), 'string') + trailer; | |
| 1465 | 1518 | } | |
| 1466 | 1519 | if (typeof value === 'number') | |
| 1467 | - return formatNumber(fn, value); | ||
| 1520 | + return formatNumber(fn, value, ctx.numericSeparator); | ||
| 1468 | 1521 | if (typeof value === 'bigint') | |
| 1469 | - return formatBigInt(fn, value); | ||
| 1522 | + return formatBigInt(fn, value, ctx.numericSeparator); | ||
| 1470 | 1523 | if (typeof value === 'boolean') | |
| 1471 | 1524 | return fn(`${value}`, 'boolean'); | |
| 1472 | 1525 | if (typeof value === 'undefined') | |
@@ -1583,8 +1636,9 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes) { | |||
| 1583 | 1636 | const elementFormatter = value.length > 0 && typeof value[0] === 'number' ? | |
| 1584 | 1637 | formatNumber : | |
| 1585 | 1638 | formatBigInt; | |
| 1586 | - for (let i = 0; i < maxLength; ++i) | ||
| 1587 | - output[i] = elementFormatter(ctx.stylize, value[i]); | ||
| 1639 | + for (let i = 0; i < maxLength; ++i) { | ||
| 1640 | + output[i] = elementFormatter(ctx.stylize, value[i], ctx.numericSeparator); | ||
| 1641 | + } | ||
| 1588 | 1642 | if (remaining > 0) { | |
| 1589 | 1643 | output[maxLength] = `... ${remaining} more item${remaining > 1 ? 's' : ''}`; | |
| 1590 | 1644 | } | |
@@ -1928,8 +1982,8 @@ function tryStringify(arg) { | |||
| 1928 | 1982 | if (!CIRCULAR_ERROR_MESSAGE) { | |
| 1929 | 1983 | try { | |
| 1930 | 1984 | const a = {}; a.a = a; JSONStringify(a); | |
| 1931 | - } catch (err) { | ||
| 1932 | - CIRCULAR_ERROR_MESSAGE = firstErrorLine(err); | ||
| 1985 | + } catch (circularError) { | ||
| 1986 | + CIRCULAR_ERROR_MESSAGE = firstErrorLine(circularError); | ||
| 1933 | 1987 | } | |
| 1934 | 1988 | } | |
| 1935 | 1989 | if (err.name === 'TypeError' && | |
@@ -1952,6 +2006,22 @@ function formatWithOptions(inspectOptions, ...args) { | |||
| 1952 | 2006 | return formatWithOptionsInternal(inspectOptions, args); | |
| 1953 | 2007 | } | |
| 1954 | 2008 | ||
| 2009 | + function formatNumberNoColor(number, options) { | ||
| 2010 | + return formatNumber( | ||
| 2011 | + stylizeNoColor, | ||
| 2012 | + number, | ||
| 2013 | + options?.numericSeparator ?? inspectDefaultOptions.numericSeparator | ||
| 2014 | + ); | ||
| 2015 | + } | ||
| 2016 | + | ||
| 2017 | + function formatBigIntNoColor(bigint, options) { | ||
| 2018 | + return formatBigInt( | ||
| 2019 | + stylizeNoColor, | ||
| 2020 | + bigint, | ||
| 2021 | + options?.numericSeparator ?? inspectDefaultOptions.numericSeparator | ||
| 2022 | + ); | ||
| 2023 | + } | ||
| 2024 | + | ||
| 1955 | 2025 | function formatWithOptionsInternal(inspectOptions, args) { | |
| 1956 | 2026 | const first = args[0]; | |
| 1957 | 2027 | let a = 0; | |
@@ -1973,9 +2043,9 @@ function formatWithOptionsInternal(inspectOptions, args) { | |||
| 1973 | 2043 | case 115: // 's' | |
| 1974 | 2044 | const tempArg = args[++a]; | |
| 1975 | 2045 | if (typeof tempArg === 'number') { | |
| 1976 | - tempStr = formatNumber(stylizeNoColor, tempArg); | ||
| 2046 | + tempStr = formatNumberNoColor(tempArg, inspectOptions); | ||
| 1977 | 2047 | } else if (typeof tempArg === 'bigint') { | |
| 1978 | - tempStr = `${tempArg}n`; | ||
| 2048 | + tempStr = formatBigIntNoColor(tempArg, inspectOptions); | ||
| 1979 | 2049 | } else if (typeof tempArg !== 'object' || | |
| 1980 | 2050 | tempArg === null || | |
| 1981 | 2051 | !hasBuiltInToString(tempArg)) { | |
@@ -1995,11 +2065,11 @@ function formatWithOptionsInternal(inspectOptions, args) { | |||
| 1995 | 2065 | case 100: // 'd' | |
| 1996 | 2066 | const tempNum = args[++a]; | |
| 1997 | 2067 | if (typeof tempNum === 'bigint') { | |
| 1998 | - tempStr = `${tempNum}n`; | ||
| 2068 | + tempStr = formatBigIntNoColor(tempNum, inspectOptions); | ||
| 1999 | 2069 | } else if (typeof tempNum === 'symbol') { | |
| 2000 | 2070 | tempStr = 'NaN'; | |
| 2001 | 2071 | } else { | |
| 2002 | - tempStr = formatNumber(stylizeNoColor, Number(tempNum)); | ||
| 2072 | + tempStr = formatNumberNoColor(Number(tempNum), inspectOptions); | ||
| 2003 | 2073 | } | |
| 2004 | 2074 | break; | |
| 2005 | 2075 | case 79: // 'O' | |
@@ -2016,21 +2086,21 @@ function formatWithOptionsInternal(inspectOptions, args) { | |||
| 2016 | 2086 | case 105: // 'i' | |
| 2017 | 2087 | const tempInteger = args[++a]; | |
| 2018 | 2088 | if (typeof tempInteger === 'bigint') { | |
| 2019 | - tempStr = `${tempInteger}n`; | ||
| 2089 | + tempStr = formatBigIntNoColor(tempInteger, inspectOptions); | ||
| 2020 | 2090 | } else if (typeof tempInteger === 'symbol') { | |
| 2021 | 2091 | tempStr = 'NaN'; | |
| 2022 | 2092 | } else { | |
| 2023 | - tempStr = formatNumber(stylizeNoColor, | ||
| 2024 | - NumberParseInt(tempInteger)); | ||
| 2093 | + tempStr = formatNumberNoColor( | ||
| 2094 | + NumberParseInt(tempInteger), inspectOptions); | ||
| 2025 | 2095 | } | |
| 2026 | 2096 | break; | |
| 2027 | 2097 | case 102: // 'f' | |
| 2028 | 2098 | const tempFloat = args[++a]; | |
| 2029 | 2099 | if (typeof tempFloat === 'symbol') { | |
| 2030 | 2100 | tempStr = 'NaN'; | |
| 2031 | 2101 | } else { | |
| 2032 | - tempStr = formatNumber(stylizeNoColor, | ||
| 2033 | - NumberParseFloat(tempFloat)); | ||
| 2102 | + tempStr = formatNumberNoColor( | ||
| 2103 | + NumberParseFloat(tempFloat), inspectOptions); | ||
| 2034 | 2104 | } | |
| 2035 | 2105 | break; | |
| 2036 | 2106 | case 99: // 'c' | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,6 +74,37 @@ assert.strictEqual( | |||
| 74 | 74 | '1180591620717411303424n 12345678901234567890123n' | |
| 75 | 75 | ); | |
| 76 | 76 | ||
| 77 | + { | ||
| 78 | + const { numericSeparator } = util.inspect.defaultOptions; | ||
| 79 | + util.inspect.defaultOptions.numericSeparator = true; | ||
| 80 | + | ||
| 81 | + assert.strictEqual( | ||
| 82 | + util.format('%d', 1180591620717411303424), | ||
| 83 | + '1.1805916207174113e+21' | ||
| 84 | + ); | ||
| 85 | + | ||
| 86 | + assert.strictEqual( | ||
| 87 | + util.format( | ||
| 88 | + '%d %s %i', 118059162071741130342, 118059162071741130342, 123_123_123), | ||
| 89 | + '118_059_162_071_741_140_000 118_059_162_071_741_140_000 123_123_123' | ||
| 90 | + ); | ||
| 91 | + | ||
| 92 | + assert.strictEqual( | ||
| 93 | + util.format( | ||
| 94 | + '%d %s', | ||
| 95 | + 1_180_591_620_717_411_303_424n, | ||
| 96 | + 12_345_678_901_234_567_890_123n | ||
| 97 | + ), | ||
| 98 | + '1_180_591_620_717_411_303_424n 12_345_678_901_234_567_890_123n' | ||
| 99 | + ); | ||
| 100 | + | ||
| 101 | + assert.strictEqual( | ||
| 102 | + util.format('%i', 1_180_591_620_717_411_303_424n), | ||
| 103 | + '1_180_591_620_717_411_303_424n' | ||
| 104 | + ); | ||
| 105 | + | ||
| 106 | + util.inspect.defaultOptions.numericSeparator = numericSeparator; | ||
| 107 | + } | ||
| 77 | 108 | // Integer format specifier | |
| 78 | 109 | assert.strictEqual(util.format('%i'), '%i'); | |
| 79 | 110 | assert.strictEqual(util.format('%i', 42.0), '42'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3104,3 +3104,52 @@ assert.strictEqual( | |||
| 3104 | 3104 | "{ ['__proto__']: { a: 1 } }" | |
| 3105 | 3105 | ); | |
| 3106 | 3106 | } | |
| 3107 | + | ||
| 3108 | + { | ||
| 3109 | + const { numericSeparator } = util.inspect.defaultOptions; | ||
| 3110 | + util.inspect.defaultOptions.numericSeparator = true; | ||
| 3111 | + | ||
| 3112 | + assert.strictEqual( | ||
| 3113 | + util.inspect(1234567891234567891234), | ||
| 3114 | + '1.234567891234568e+21' | ||
| 3115 | + ); | ||
| 3116 | + assert.strictEqual( | ||
| 3117 | + util.inspect(123456789.12345678), | ||
| 3118 | + '123_456_789.123_456_78' | ||
| 3119 | + ); | ||
| 3120 | + | ||
| 3121 | + assert.strictEqual(util.inspect(10_000_000), '10_000_000'); | ||
| 3122 | + assert.strictEqual(util.inspect(1_000_000), '1_000_000'); | ||
| 3123 | + assert.strictEqual(util.inspect(100_000), '100_000'); | ||
| 3124 | + assert.strictEqual(util.inspect(99_999.9), '99_999.9'); | ||
| 3125 | + assert.strictEqual(util.inspect(9_999), '9_999'); | ||
| 3126 | + assert.strictEqual(util.inspect(999), '999'); | ||
| 3127 | + assert.strictEqual(util.inspect(NaN), 'NaN'); | ||
| 3128 | + assert.strictEqual(util.inspect(Infinity), 'Infinity'); | ||
| 3129 | + assert.strictEqual(util.inspect(-Infinity), '-Infinity'); | ||
| 3130 | + | ||
| 3131 | + assert.strictEqual( | ||
| 3132 | + util.inspect(new Float64Array([100_000_000])), | ||
| 3133 | + 'Float64Array(1) [ 100_000_000 ]' | ||
| 3134 | + ); | ||
| 3135 | + assert.strictEqual( | ||
| 3136 | + util.inspect(new BigInt64Array([9_100_000_100n])), | ||
| 3137 | + 'BigInt64Array(1) [ 9_100_000_100n ]' | ||
| 3138 | + ); | ||
| 3139 | + | ||
| 3140 | + assert.strictEqual( | ||
| 3141 | + util.inspect(123456789), | ||
| 3142 | + '123_456_789' | ||
| 3143 | + ); | ||
| 3144 | + assert.strictEqual( | ||
| 3145 | + util.inspect(123456789n), | ||
| 3146 | + '123_456_789n' | ||
| 3147 | + ); | ||
| 3148 | + | ||
| 3149 | + util.inspect.defaultOptions.numericSeparator = numericSeparator; | ||
| 3150 | + | ||
| 3151 | + assert.strictEqual( | ||
| 3152 | + util.inspect(123456789.12345678, { numericSeparator: true }), | ||
| 3153 | + '123_456_789.123_456_78' | ||
| 3154 | + ); | ||
| 3155 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments