-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add property, method, and indexed item splatting support #11003
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
Conversation
This comment has been minimized.
This comment has been minimized.
|
@KirkMunro, successfully started retry of |
iSazonov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to add more tests that splatting (old and new) works (like Get-Date @DaTa and Get-Date @data.Parameters )
Co-Authored-By: Ilya <darpa@yandex.ru>
Co-Authored-By: Ilya <darpa@yandex.ru>
Agreed. I added some basic splatting tests since we didn't have specific tests in place already. |
|
@KirkMunro Please fix CIs failures. |
|
@PoshChan please retry all |
|
@KirkMunro, successfully started retry of |
|
Should we update RFC0002 for the syntax? |
|
@iSazonov Someone can if they want to. I shared the syntax 3+ years ago, before that RFC was approved, but @lzybkr didn't add it to the RFC at the time. |
|
@PowerShell/powershell-committee reviewed this, and while we don't see a technical risk or breaking change, we're having trouble coming up with a compelling, real-world scenario to justify adding it to the language. Especially considering |
|
The 3rd case is exactly the scenario where this is needed, because it doesn't always work. For example: function Test-Splat {
[CmdletBinding()]
param(
[parameter(mandatory)]
[string]
$Name
)
$sb = {Get-Service @PSBoundParameters}
& $sb
}
Test-Splat -Name wuauservIf you run that command, you'll get all services. Why? Because As a best practice, I don't use Here is an example demonstrating what I would have to do instead if I wanted to make what I shared above work today: function Test-Splat {
[CmdletBinding()]
param(
[parameter(mandatory)]
[string]
$Name
)
$sb = {
$cmdletParams = $PSCmdlet.MyInvocation.BoundParameters
Get-Service @cmdletParams
}
& $sb
}
Test-Splat -Name wuauservThe use of intermediate variables here feels unnecessary and it's just extra code to maintain. I want to be able to accomplish the same like this: function Test-Splat {
[CmdletBinding()]
param(
[parameter(mandatory)]
[string]
$Name
)
$sb = {
Get-Service @PSCmdlet.MyInvocation.BoundParameters
}
& $sb
}
Test-Splat -Name wuauservThe other scenarios are added because it makes much more sense to me syntactically to be able to use the new syntax, which is very clear in intent, than to add an overly complex splat-subexpression syntax such as Further, and quite important (so make sure you read/get this), these changes open the door for something else that is needed with splatting. One thing missing from splatting is the ability to perform a partial hashtable splat. Splat in one or more parameters, and only if they are present as keys in the hashtable. Splat in all parameters in the hashtable except for one or more parameters. Those scenarios (manipulating hashtables to get a subset hashtable easily without having to write complicated code) have benefits that extend beyond splatting and are useful elsewhere in scripts. By extending the splatting syntax to support member invocation and indices, we're opening the door for hashtable manipulation to be added independently of splatting, as it should be, such that splatting can just support it once it is added (maybe for free, maybe with a minor addition, depending on the syntax used for hashtable manipulation). If this is not clear, let me know and I'll go into more detail. This need, and the justification for the syntax shared here, is crystal clear to me, keeping splatting focused on exactly what it was designed to do (take an array or a hashtable and splat those values into an invocation), while leveraging other current functionality (accessing members, accessing an indexed item) and new functionality (hashtable manipulation) using the same syntax that you would use elsewhere. PowerShell is object-oriented, with properties and methods, as well as indexable collections. When working with variables, we can access properties and methods and indexed items in collections with ease. Why should we have to use a different syntax to do so when splatting, or inject intermediate variables, when we can simply change a For some reason, when it comes to splatting improvements such as inline splatting and subexpression splatting and the discussions surrounding it, there seems to be a strong bias for new, obtuse syntax over syntax that maintains consistency with how things have already been written and used in PowerShell since v1, and I just don't get why. At any rate, I'll keep pushing improvements into the language the way I see them being most consistent and a best fit for what's already there, and this PR is an example of just that. |
|
Funny enough, I ran into this just the other day. With the WinSCP PSModule there are parameters for HostName, Port, SshPrivateKeyPath, etc. They all match perfectly for Splatting. However, when you have multiple servers, you have to namespace them. Ideally, I would do this: $config = @{
QA = @{
Host = @{
HostName = 'abc'
Port = 22
}
Prod = @{
Host = @{
HostName = 'abc'
Port = 22
}
}
}
New-WinSCPOption @config.QA.Host
New-WinSCPOption @config.Prod.HostToday, I would have to store both of those configurations into another variable first to use them: $qaConfig = $config.QA.Host
$prodConfig = $config.Prod.Host
New-WinSCPOption @qaConfig
New-WinSCPOption @prodConfigIt just adds more work when I could have just splat directly to them. |
|
@PowerShell/powershell-committee Please re-review as the author has responded. |
|
@dragonwolf83 we in the @PowerShell/powershell-committee don't really understand why, in the 1st example where you set a variable for the params, is unclear Unfortunately, we didn't have @BrucePay today in our @PowerShell/powershell-committee meeting, would love to get his take as well: as @JamesWTruher raised, this is all very tied to the parameter binder, and he may have an opinion there. Similarly, @KirkMunro, I'm really not seeing why the 2nd example is fundamentally more clear or concise to justify the additional complexity. I won't pretend to understand exactly in what way this is enabling future hashtable manipulation features, but we should establish first that those features are useful before leading with an implementation that we're not sure is a pre-requisite. You may have posted about those somewhere we haven't yet gotten to, but the value that said features would enable should be the front of the pipeline. |
|
@PowerShell/powershell-committee reviewed this, we are ok with the intent. We ask that the tests be increased to cover multiple values rather than splatting a single value. |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
|
Closing. See #10238 (comment). |
PR Summary
Like PR's #10984 and #10073, this PR enhances the splatting capabilities in PowerShell.
With this PR in place, users are able to splat members (properties and methods) as well as indexed items into an invocation. It doesn't matter how many levels deep you go with your expression.
Examples:
The only question I have is whether or not this functionality needs to be behind an experimental feature. If you review the code changes, you'll see that adding this support was very, very easy, and I believe the changes are low risk, so I don't know that it is worth the added complexity of wrapping these in an experimental feature.
PR Context
This functionality has already been identified as desirable for PowerShell as part of RFC0002.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.