Skip to content

Conversation

@KirkMunro
Copy link
Contributor

@KirkMunro KirkMunro commented Nov 4, 2019

PR Summary

Similar to #10073, this PR enhances the splat functionality that is available in PowerShell. Instead of doing this by extending operators, this PR adds a common -splat parameter of type [IDictionary[]] that supports the following new features:

  • inline splat of one or more hashtables
  • splat of one or more hashtables by value returned from a:
    • variable
    • property
    • command

The functionality in this PR is only available if you have the PSCommonSplatParameter experimental feature enabled.

PR Context

This PR helps because it extends splatting to support quite a few features that were requested by the community and described in RFC0002, which can currently be found here. Specifically, this allows users to use inline splatting of literal hashtables, variables, properties, the result of methods, or the result of commands.

I have opened this PR to offer an alternative syntax to the syntax offered in #10073 while also supporting a broader set of scenarios necessary for easier splatting in scripts.

Here are some examples demonstrating how this can be used:

# Splat a literal hashtable
Get-Date -splat @{Year=1971;Month=10;Day=20}

# Splat a property value
$getDate = [pscustomobject]@{
    Parameters = @{Year=1971;Month=10;Day=20}
}
Get-Date -splat $getDate.Parameters

# Splat the results of a command:
function Get-ParameterSet {
    @{Year=1971;Month=10;Day=20}
}
Get-Date -splat (Get-ParameterSet)

PR Checklist

@lzybkr
Copy link
Contributor

lzybkr commented Nov 4, 2019

I see a couple of issues with this approach.

First, I think this breaks a common scenario:

sleep -s 10

Basically any command that has exactly 1 parameter beginning with S would no longer be callable by specifying -s.

Second, a common parameter would also not work with non-cmdlet binding functions because common parameters are not added to those functions. I think it would be a mistake to introduce an alternative syntax for splatting that doesn't work everywhere, especially when the incorrect syntax might appear to work silently as is typically the case where $args collects the "extra" parameters.

@KirkMunro

This comment has been minimized.

@PoshChan
Copy link
Collaborator

PoshChan commented Nov 4, 2019

@KirkMunro, successfully started retry of PowerShell-CI-static-analysis

@KirkMunro
Copy link
Contributor Author

KirkMunro commented Nov 4, 2019

First, I think this breaks a common scenario:

sleep -s 10

Basically any command that has exactly 1 parameter beginning with S would no longer be callable by specifying -s.

There were never any guarantees with non-alias shorthand for parameter names that such syntax will continue to work over time. Only parameter aliases can guarantee consistent syntax, and commands where it is very common to use that syntax would be better off assigning those aliases so that they do continue to work over time. For the specific scenario mentioned here, we can add a s alias for the -seconds parameter in Start-Sleep if that is a concern.

Don't get me wrong...I get the concern -- there is muscle memory to think about. That said though, shorthand parameter names don't always work from version to version because parameters are added to commands over time. I also recognize that this is a common parameter, so more invasive, vs. a command author adding a parameter and thinking to add aliases to support specific shorthand syntax as they add that parameter. The guarantee still isn't there though, unless aliases are used.

Second, a common parameter would also not work with non-cmdlet binding functions because common parameters are not added to those functions. I think it would be a mistake to introduce an alternative syntax for splatting that doesn't work everywhere, especially when the incorrect syntax might appear to work silently as is typically the case where $args collects the "extra" parameters.

You're right that this wouldn't work for basic functions. A rule should be added to PSSA to pick up on such things and warn users. If there isn't a rule already to identify when a basic function is passed common parameters, there should be, regardless of what happens with this PR. Your argument about common parameters appearing to work silently with $args collecting "extra" parameters isn't unique to the proposed -splat common parameter. It applies to all common parameters (-ErrorAction, -WarningAction, etc.). Users who create functions and who want common parameter support need to learn that CmdletBinding is required.

@KirkMunro

This comment has been minimized.

@PoshChan
Copy link
Collaborator

PoshChan commented Nov 4, 2019

@KirkMunro, successfully started retry of PowerShell-CI-static-analysis

@KirkMunro

This comment has been minimized.

@PoshChan
Copy link
Collaborator

PoshChan commented Nov 4, 2019

@KirkMunro, successfully started retry of PowerShell-CI-Windows

@bergmeister
Copy link
Contributor

bergmeister commented Nov 4, 2019

The only concern that I have is the name Splat:
PowerShell's parameters are usually not shortened but more importantly the word splatting/splat is a word that is not very intuitive/explanatory to someone that does not know about PowerShell splatting or is not a native English speaker.
I do not have a better name but it would be great to have a name that is more self-explanatory.
In Python they call it 'parameter unpacking'
https://www.python.org/dev/peps/pep-0448/

@vexx32
Copy link
Collaborator

vexx32 commented Nov 4, 2019

We could opt for something like -Parameters with a short alias -Params 🤔

@KirkMunro
Copy link
Contributor Author

KirkMunro commented Nov 4, 2019

We could opt for something like -Parameters with a short alias -Params 🤔

While I like the sound of it, I think -Parameters is too generic and would be a high risk for collision. For example, Get-Help has a -Parameter parameter. It would be confusing to have both -Parameter and -Parameters in any cmdlet. OTOH, the -Splat name is not likely to result in collision or confusion with other parameter names.

Since the concept of splatting already needs to be learned, I like the explicit nature of the -Splat name, myself. Plus, visibility of that as a word gives users something to search for so that they can learn what it does.

@KirkMunro
Copy link
Contributor Author

I should note, I did consider including @ as an alias for the -Splat parameter, but since PowerShell treats -@ as a positional value (it isn't recognized as a parameter name today), that would be a breaking change. I'm not opposed to making such a change, but I didn't want it in the first implementation of this PR.

@bergmeister
Copy link
Contributor

How about -ParameterSplat? Or -SplattedParameter? Or -ParameterObject?

@KirkMunro

This comment has been minimized.

@PoshChan
Copy link
Collaborator

PoshChan commented Nov 4, 2019

@KirkMunro, successfully started retry of PowerShell-CI-Linux

@ThomasNieto
Copy link
Contributor

What about -PSArgumentList?

@bergmeister
Copy link
Contributor

List is a type, that might be confusing. PS seems a bit redundant and not common for parameter names

@ThomasNieto
Copy link
Contributor

We keep having discussions in various threads when adding common parameters how not to clobber existing parameters. It could have been avoided if a reserved prefix was used, like with cmdlets. It's slightly off topic for this specific PR but wanted to bring it up for the overall common parameter discussion.

@ghost ghost added the Review - Needed The PR is being reviewed label May 27, 2020
@ghost
Copy link

ghost commented May 27, 2020

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Mainainer, Please provide feedback and/or mark it as Waiting on Author

@adityapatwardhan adityapatwardhan removed this from the 7.1.0-preview.4 milestone Jun 29, 2020
@KirkMunro
Copy link
Contributor Author

Closing.

@KirkMunro KirkMunro closed this Apr 24, 2021
@SeidChr
Copy link

SeidChr commented May 26, 2021

no -splat, no -@, no @@ yet, will there be anything like that in the future? It seems like all approaches to improve splatting and thus usability are declined. Is there anything else in the work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review - Needed The PR is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.