-
Notifications
You must be signed in to change notification settings - Fork 383
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
$null should be on the left side of equality comparison - ignore Arrays? #1227
Comments
It is needed FOR arrays ... Change your line It is arguable wether the problem this rule is trying to fix applies to -NE $null but with -EQ it also applies to zero, $false or "" The -eq (or -gt , or -Match etc) opeator applied to an array gives the members for which it is true - it is easier to see with zeros than nulls : try
The the first gives 1 zero and the second give 2 zeros. An array containing one element which converts boolean false is treated as false, but an array with multiple items is boolean true even if every item is false. try
Tests for -eq 1 or -eq true etc don't need multiple instances to give a result of true but tests for 0, false , "" or null do.
So do these two
A test which checks for "something is/is-not X" but gives different results depending on what is not X or how many are X is exactly the sort of thing which should give a warning. The same problem even applies to
|
@jhoneill Thanks for the explanation. You're probably right. I will accept if this is something that can't be addressed. Thank you again! |
I think the heart of the issue is that this code: $Test1 = While ($Array.Status -ne $null) {
$true
foreach ($A in $Array) {
$A.Status = $null
}
} is doing a Compare with: $Test1 = While ($Array.Status -ne 'Done') {
$true
foreach ($element in $Array) {
$element.Status = 'Done'
}
} PSScriptAnalyzer relies on certain heuristics -- assumptions about your intent and how code is being used. And the assumption in this particular rule is that when people compare with Most of the time that's correct, and this rule has probably saved plenty of people trouble. But in your case it doesn't apply -- in fact what you're doing is exactly the behaviour it's trying to warn about (which is perfectly valid behaviour and your usage makes sense). But I think the answer here is to just switch out the |
I've fixed my code since I've reported it initially. That is the "code" I was using (and the reason why I've reported it - and had a blog post about it) Original code: function Stop-Runspace {
[cmdletbinding()]
param(
[Array] $Runspaces,
[string] $FunctionName,
[System.Management.Automation.Runspaces.RunspacePool] $RunspacePool,
[switch] $ExtendedOutput
)
[Array] $List = while ($Runspaces.Status -ne $null) {
#[Array] $List = While (@($Runspaces | Where-Object -FilterScript {$null -ne $_.Status}).count -gt 0) {
foreach ($Runspace in $Runspaces | Where-Object { $_.Status.IsCompleted -eq $true }) {
$Errors = foreach ($e in $($Runspace.Pipe.Streams.Error)) {
Write-Error -ErrorRecord $e
$e
}
foreach ($w in $($Runspace.Pipe.Streams.Warning)) {
Write-Warning -Message $w
}
foreach ($v in $($Runspace.Pipe.Streams.Verbose)) {
Write-Verbose -Message $v
}
if ($ExtendedOutput) {
@{
Output = $Runspace.Pipe.EndInvoke($Runspace.Status)
Errors = $Errors
}
} else {
$Runspace.Pipe.EndInvoke($Runspace.Status)
}
$Runspace.Status = $null
}
}
$RunspacePool.Close()
$RunspacePool.Dispose()
if ($List.Count -eq 1) {
return , $List
} else {
return $List
}
} Fixed code (that someone suggested): function Stop-Runspace {
[cmdletbinding()]
param(
[Array] $Runspaces,
[string] $FunctionName,
[System.Management.Automation.Runspaces.RunspacePool] $RunspacePool,
[switch] $ExtendedOutput
)
[Array] $List = While (@($Runspaces | Where-Object -FilterScript {$null -ne $_.Status}).count -gt 0) {
foreach ($Runspace in $Runspaces | Where-Object { $_.Status.IsCompleted -eq $true }) {
$Errors = foreach ($e in $($Runspace.Pipe.Streams.Error)) {
Write-Error -ErrorRecord $e
$e
}
foreach ($w in $($Runspace.Pipe.Streams.Warning)) {
Write-Warning -Message $w
}
foreach ($v in $($Runspace.Pipe.Streams.Verbose)) {
Write-Verbose -Message $v
}
if ($ExtendedOutput) {
@{
Output = $Runspace.Pipe.EndInvoke($Runspace.Status)
Errors = $Errors
}
} else {
$Runspace.Pipe.EndInvoke($Runspace.Status)
}
$Runspace.Status = $null
}
}
$RunspacePool.Close()
$RunspacePool.Dispose()
if ($List.Count -eq 1) {
return , $List
} else {
return $List
}
} I'm learning a lot from you guys. Thank you. And to add, the warning is a warning that I was applying without "thinking". I've even encouraged @bergmeister to add "auto" fix by default for finding this in your code during formatting. And it seems that it isn't that straightforward and without manual testing may bring unexpected results. |
I'm happy to close this issue if you don't need it? |
Before submitting a bug report:
Steps to reproduce
Wrote a short blog post about it: https://evotec.xyz/the-curious-case-of-null-should-be-on-the-left-side-of-equality-comparisons-psscriptanalyzer/
But the code is as below:
It will never end for $Test2.
Expected behavior
No tip for the Array.
Actual behavior
Tip that tells the user to fix the code.
Environment data
The text was updated successfully, but these errors were encountered: