Repository navigation
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, Patrick Meinecke (@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.
Activity
[-]Enable simple detention of [AutomationNull]::Value with -is [AutomationNull][/-][+]Enable simple detection of [AutomationNull]::Value with -is [AutomationNull][/+]briantist commentedon Dec 22, 2020
I really like this proposal.
The differences between
$nulland "nothing" confound users who inevitably run into it, and the ones who are curious enough to try to understand why and make clear comparisons end up disappointed and with a view of PowerShell as a "weird" language (or at worst one they can't trust).True story: I worked at a company where the team who used PowerShell the most had as their team's chat description:
The concept of a
$nullresult vs. "no result" is not difficult to understand, but only being able to reason about a result implicitly instead of being able to just ask the language is not a good UX.$value -is [AutomationNull]is clear and concise.CopaceticMeatbag commentedon Oct 28, 2022
Any chance this is going to be looked at eventually? The current implementation makes zero intuitive sense, and I think the example below is a very a basic and common use case. What's the hold up 2 years on?
SeeminglyScience commentedon Oct 28, 2022
Mike (@CopaceticMeatbag) This issue is about an easier way to detect autonull, not a change in the behavior. That behavior in particular is relied upon heavily so I would not expect it to change.
On an unrelated note, this issue is missing a needs triage tag, adding so the Engine WG can discuss it.
CopaceticMeatbag commentedon Nov 1, 2022
Patrick Meinecke (@SeeminglyScience) yes I'm sorry I should've been clearer; I think
$value -is [AutomationNull]is a great halfway solution and would at least give me an option to work with.I read through issue #9997 and don't understand how Bruce Payette (@bpayette) 's comments make sense to nullify the whole discussion. E.g. "The intent was to make AutomationNull as invisible to script users as possible". Ok sure, but PS is returning an [AutomationNull] result to me, and I'm trying to confirm that, and the response is "you're not meant to use that"? So why return it then if I'm not meant to use it? Feels like the PS team is more than happy shifting the burden onto the end user as a 'fix' for this issue.
SeeminglyScience commentedon Jan 10, 2023
The Engine WG discussed this yesterday and agree to go forward with my proposal laid out in
#9997 (comment)with the requirement that #18914 is implemented and the currently pubternal type is decorated withHiddenAttribute.It should also be noted that we decided that a type accelerator was not necessary as it's an uncommon scenario.
microsoft-github-policy-service commentedon Nov 16, 2023
microsoft-github-policy-service commentedon Nov 16, 2023
microsoft-github-policy-service commentedon Nov 16, 2023
microsoft-github-policy-service commentedon Nov 23, 2023
daxian-dbw commentedon Jun 10, 2024
Reopen this "up-for-grab" issue.