-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
- Follow-up from AutomationNull Behaviour #9997, which lacked a clear proposal.
- Related to Make -is [pscustomobject] and -as [pscustomobject] work meaningfully #11921 (
-is [pscustomobject]) and Add -is $null and -isnot $null support to operators and Where-Object #10704 (-is $null)
Summary of the new feature/enhancement
Enable the following -is test to allow for a PowerShell-idiomatic detection of the [System.Management.Automation.Internal.AutomationNull]::Value value that commands that output "nothing" technically output.
# `& {}` outputs "nothing", which is technically [System.Management.Automation.Internal.AutomationNull]::Value
PS> & {} -is [AutomationNull] # WISHFUL THINKING
TrueIn expression contexts [System.Management.Automation.Internal.AutomationNull]::Value is treated like $null, but there are contexts where the distinction matters:
In the pipeline:
# A true $null is sent through the pipeline.
PS> $null | % { 'here' }
here
# [System.Management.Automation.Internal.AutomationNull]::Value is NOT sent through the pipeline
# - it is an empty enumeration.
PS> & { } | % { 'here' }
# NO outputAlso, because the switch statement treats its operand as an enumeration, a [System.Management.Automation.Internal.AutomationNull]::Value value causes the statement to be skipped altogether; that is, it is effectively ignored:
$val = & {}
# Because $val contains [System.Management.Automation.Internal.AutomationNull]::Value,
# the switch statement is effectively ignored;
switch ($val) {
default { 'hi' }
}Operators behave inconsistently with AutomationNull as the LHS (see #3866):
PS> [System.Management.Automation.Internal.AutomationNull]::Value -match 'foo'
# NO OUTPUT - LHS was interpreted as *collection*
PS> [System.Management.Automation.Internal.AutomationNull]::Value -eq 'foo'
False # LHS was interpreted as a *scalar*In short: Because [System.Management.Automation.Internal.AutomationNull]::Value causes observable differences in behavior from $null, it must be discoverable.
Proposed technical implementation details (optional)
Note: Strictly speaking, [System.Management.Automation.Internal.AutomationNull]::Value is of type [System.Management.Automation.PSObject], but treating it as an instance of AutomationNull would be a helpful "white lie", similar to the one -is already tells when it reports a [psobject] wrapper's .BaseObject value's type as the type.
However, @SeeminglyScience's proposed implementation here would actually resolve this issue, via a new, public System.Management.Automation.AutomationNull wrapper, for which an [AutomationNull] type accelerator would have to be defined.