Skip to content

Stop stream variables (e.g. OutVariable) becoming ArrayLists#6409

Closed
rjmholt wants to merge 1 commit intoPowerShell:masterfrom
rjmholt:out-variable-array-3154
Closed

Stop stream variables (e.g. OutVariable) becoming ArrayLists#6409
rjmholt wants to merge 1 commit intoPowerShell:masterfrom
rjmholt:out-variable-array-3154

Conversation

@rjmholt
Copy link
Copy Markdown
Collaborator

@rjmholt rjmholt commented Mar 16, 2018

PR Summary

Fixes #3154 and #3773.

Currently, when a value is passed out of a command using -OutVariable, we use an ArrayList to collect the value to give back to the user, but we leak that detail so that the variable comes back as an ArrayList and not object[] or as itself.

This PR fixes this, so that implementation differences between

$null = Write-Output -OutVariable x $value; $x

and

Write-Output $value

are transparent.

To summarize:

Input Non-OutVar Result Type Old Result Type New Result Type
'Hello' System.String System.Collections.ArrayList System.String
@(1, 2) object[] System.Collections.ArrayList object[]
[System.Collections.ArrayList]::new(@(1,2)) object[] System.Collections.ArrayList object[]
@(,[System.Collections.ArrayList]::new(@(1,2)) System.Collections.ArrayList System.Collections.ArrayList System.Collections.ArrayList
$null System.Collections.ArrayList

This is technically a breaking change. The PowerShell commitee reviewed it in #3154. A suggested classification was as a class-3 unlikely grey area change, where the new behaviour is more likely to be expected.

PR Checklist

@iSazonov iSazonov added Breaking-Change breaking change that may affect users Committee-Reviewed PS-Committee has reviewed this and made a decision labels Mar 16, 2018
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please use more informative variable name then v?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems return is not correct term in comments here and below.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this assign? It seems is default.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you take a case like

$x = Write-Output -OutVariable ov @()

Then $x is $null but without the assignment, $ov is an empty object[]. If our intent is for them to be the same, then I think we need the assignment to null here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation. I believe it should be in 4th position.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used once - please move directly in -TestCases.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to do this. Is there an example of the code style you can link where $TestCases is inlined in the call?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation. I believe it should be 8th position.

@rjmholt
Copy link
Copy Markdown
Collaborator Author

rjmholt commented Mar 16, 2018

Quick question - the [feature] checkbox - is that supposed to just be in the commit message and not in the title of the PR?

@rjmholt rjmholt changed the title [Feature] Stop stream variables (e.g. OutVariable) becoming ArrayLists Stop stream variables (e.g. OutVariable) becoming ArrayLists Mar 16, 2018
@Jaykul
Copy link
Copy Markdown
Contributor

Jaykul commented Mar 16, 2018

This would be a pretty major breaking change...

@markekraus
Copy link
Copy Markdown
Contributor

markekraus commented Mar 16, 2018

Umm... I disagree that this is a Bucket 3 breaking change and request it be classified as Bucket 1. Especially if you are going to return a string as a String instead of an ArrayList.

I have been preaching for years as well as using the -OutVariable specifically because it always returns an ArrayList. Since it is always a predictable type you can always use the same methods and actions on it.

If Strings are suddenly returned... this becomes problematic:

$null = Get-MaybeOneOrMoreStrings -OutVariable Results
$FirstString = $Results[0]

This is a simplified example of something I make great use of in many places.

@SteveL-MSFT

@markekraus
Copy link
Copy Markdown
Contributor

markekraus commented Mar 16, 2018

To clarify, I would be ok with these returning any collection type (changed in a major version bump). In order of preference List<Object>, ArrayList, Object[] (an object array can't be used, see my other comment.). But I am wholeheartedly against this returning single values and not a collection.

@markekraus
Copy link
Copy Markdown
Contributor

This PR breaks the following usage:

$Results = [System.Collections.ArrayList]::new()
$Results.Add('before')
Write-Output 'a' -OutVariable '+Results'
$Results.Add('After')

$Results.Count
$Results[0]
$Results[1]
$Results[2]
Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
At line:1 char:1
+ $Results.Add('After')
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException

Copy link
Copy Markdown
Contributor

@markekraus markekraus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have PowerShell Committee review this again. I believe this is a Bucket 1 breaking change and should go through RFC.

@SteveL-MSFT SteveL-MSFT added Review - Committee The PR/Issue needs a review from the PowerShell Committee and removed Committee-Reviewed PS-Committee has reviewed this and made a decision labels Mar 16, 2018
@rjmholt
Copy link
Copy Markdown
Collaborator Author

rjmholt commented Mar 16, 2018

Apologies -- after reading through #3154, the responses there seemed to encourage the change.

Since I've already created a PR, I've gone ahead an created an RFC, so feel free to comment there.

I may also submit a PR to change the docs to emphasise and strengthen the language on RFCs for breaking changes. After going through the PR checklist, I didn't catch the reference to possibly submitting an RFC.

I will mothball this PR for now.

@rjmholt rjmholt closed this Mar 16, 2018
@markekraus
Copy link
Copy Markdown
Contributor

@rjmholt No worries! if I had seen those other issues I would have raised a stink about it needing an RFC before the PR! 😆

@iSazonov
Copy link
Copy Markdown
Collaborator

iSazonov commented Mar 19, 2018

Quick question - the [feature] checkbox - is that supposed to just be in the commit message and not in the title of the PR?

In last commit header only.

@SteveL-MSFT SteveL-MSFT removed the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Aug 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Breaking-Change breaking change that may affect users

Projects

None yet

Development

Successfully merging this pull request may close these issues.

-OutVariable doesn't unwrap single-object output and creates [System.Collections.ArrayList] values rather than [System.Object[]]

5 participants