-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Summary of the new feature/enhancement
The output formatting system's purpose is to present data to the human reader.
(As such - because the formatted output isn't meant for programmatic processing - it isn't part of PowerShell's breaking-changes contract.)
Currently, large numbers are output without thousands separators, i.e. without grouping the digits for easier comprehension.
I suggest applying this grouping to all numbers (that aren't explicitly formatted via formatting data):
# WISHFUL THINKING - but you can get a preview with the prototype below.
# Number by itself (out-of-band formatting)
PS> 1000
1,000
# Implicit in-band formatting (table or list)
PS> @{ num = 1000 }
Name Value
---- -----
num 1,000
# Should also automatically apply to types with explicit formatting data
# (unless number formatting is part of a given list item / table column).
# Note the "Size" column.
PS> Get-Item $PROFILE
Directory: /Users/jdoe/.config/powershell
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
-rw-r--r-- jdoe staff 10/23/2019 22:31 1,934 Microsoft.PowerShell_profile.ps1
As @ThomasNieto proposes below, a new preference variable and new switch for the Format-* cmdlets could allow opting into the old behavior. E.g.: $PSThousandsGrouping with values $true and $false (default $true), and switch
-ThousandsGrouping.
Proposed technical implementation details (optional)
Here's a quick prototype that uses the ETS. It is not the suggested implementation, for reasons of both performance and also changing the behavior of explicit .ToString() calls.
A proper implementation would require modifying the formatting system itself.
# Prototype:
[int16], [int], [long], [double], [decimal], [bigint], [uint16], [uint], [uint64] | % {
Update-TypeData -TypeName $_.FullName -MemberType ScriptMethod -MemberName ToString -Value {
# Determine how many decimal places there are in the original representation.
# Note: PowerShell's string interpolation uses the *invariant* culture, so '.'
# can reliably be assumed to be the decimal mark.
$numDecimalPlaces = ("$this" -replace '^[^.]+(?:.(.+))?', '$1').Length
# Format with thousands grouping and the same number of decimal places.
# Note: This will create a culture-sensitive representation
# just like with the default output formatting.
# CAVEAT:
# To avoid a crash (from infinite recursion?), both .psobject.BaseObject
# and the -f operator must be used.
# ($this.psobject.BaseObject.ToString("...") also crashes).
"{0:N$numDecimalPlaces}" -f $this.psobject.BaseObject
} -Force
}