You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
"-"-prefixed barewords in argument mode should always be interpreted as parameter names #4591
#4578 shows that you can sometimes use --prefixed bareword as parameter values - namely only if the bareword happens not to (prefix)-match a parameter name of the target command - and when such barewords are recognized as values, they don't behave the same way as non---prefixed barewords with respect to interpolation and being recognized as a single argument.
The "workaround" is in my opinion the preferred style - use quotes.
it seems that the desired solution is to disallow--prefixed barewords as values and to always assume that such an unquoted--prefixed token is a parameter name.
# Currently interpreted as *value*, because no Write-Output parameter name starts with -z.# This should no longer be supported.>Write-Output-InputObject -z
-z
# Interpreted as *parameter name*, because -n prefix-matches parameter -NoEnumeration>Write-Output-InputObject -n
Write-Output : Missing an argument for parameter 'InputObject'. Specify a parameter of type 'System.Management.Automation.PSObject[]' and try again.
Get-Command accepts it's parameter ArgumentList with ValueFromRemainingArguments, and in this scenario, values that look like parameters are expected. The use case here is to help determine dynamic parameters (which is why I used cert: to show the syntax includes the correct dynamic parameters.)
I suppose there could be a refinement to ValueFromRemainingArguments to specify that parameters are not arguments - that might be useful and avoid confusion in a few cases, but I'm not sure Write-Object is such a case as parameters are rarely named with that cmdlet.
For non-cmdlet binding functions or for ValueFromRemainingArguments, the current behavior is definitely by design. In other cases, it might be of questionable value, but the behavior is consistent and I guess easy to explain.
The parser doesn't interpret the script any differently - you can verify this by looking at the AST, so this is just a parameter binding issue.
I suppose there could be a refinement to ValueFromRemainingArguments to specify that parameters are not arguments - that might be useful and avoid confusion in a few cases
Don't get that, but let me point out how ValueFromRemainingArguments is confusing the way it works currently, using a less mind-bending example than Get-Command, namely Join-Path (as an aside: nothing in Join-Path -? tells us that ValueFromRemainingArguments is supported):
# OK: non-"-"-prefixed tokens>Join-Path a b c
a/b/c
# OK: quoted "-"-prefixed tokens.>Join-Path'-z''-z''-z'-z/-z/-z
# BROKEN: not clear what's happening here.>Join-Path-z -z -z
cmdlet Join-Path at command pipeline position 1
Supply values for the following parameters:
Path[0]:
That said, not having to quote constantly due to uncertainty over how barewords will be interpreted would be nice - after all, use of barewords is a perk of argument mode / shell-like syntax.
the behavior is consistent and I guess easy to explain.
I'm not trying to be flippant when I say: Please do.
I'm honestly confused at this point, so if you can give a concise, comprehensive explanation of how --prefixed barewords are meant to be handled in all scenarios - current bugs notwithstanding - based on rules people can actually keep in their heads, without needing to know how the parameter sausage is made, I'd personally appreciate it, but, as usual, documenting it for the world at large is the right thing to do.
Also worth noting that PowerShell already has an unrelated bareword-rules complexity problem - see #3217
P.S.: Let's not forget that when a -<letter>-prefixed bareword does make it through as a value, it is not expanded the same way as non --prefixed bareword, as originally discussed in #4578:
>Join-Path a b z$HOME
a/b/zhome/jdoe
>Join-Path a b -z$HOME
a/b/-z$HOME# no expansion
Activity
lzybkr commentedon Aug 16, 2017
I believe this is very much by design.
These parameters as arguments are often parameters themselves, but they are unknown to the cmdlet accepting them.
Here is a good example:
Get-Commandaccepts it's parameterArgumentListwithValueFromRemainingArguments, and in this scenario, values that look like parameters are expected. The use case here is to help determine dynamic parameters (which is why I usedcert:to show the syntax includes the correct dynamic parameters.)I suppose there could be a refinement to
ValueFromRemainingArgumentsto specify that parameters are not arguments - that might be useful and avoid confusion in a few cases, but I'm not sureWrite-Objectis such a case as parameters are rarely named with that cmdlet.mklement0 commentedon Aug 16, 2017
Leaving
ValueFromRemainingArgumentsaside for now, which is not that common:While
Write-Outputwas not the best example, there are definitely cmdlets where this inconsistency is more likely to arise:Get-Item -LiteralPath -zvs.Get-Item -LiteralPath -p, for instance.That the specific content of a token (beyond its lexical structure) would decide its syntactical role situtationally sounds iffy to me.
lzybkr commentedon Aug 16, 2017
For non-cmdlet binding functions or for
ValueFromRemainingArguments, the current behavior is definitely by design. In other cases, it might be of questionable value, but the behavior is consistent and I guess easy to explain.The parser doesn't interpret the script any differently - you can verify this by looking at the AST, so this is just a parameter binding issue.
mklement0 commentedon Aug 16, 2017
Don't get that, but let me point out how
ValueFromRemainingArgumentsis confusing the way it works currently, using a less mind-bending example thanGet-Command, namelyJoin-Path(as an aside: nothing inJoin-Path -?tells us thatValueFromRemainingArgumentsis supported):lzybkr commentedon Aug 17, 2017
Yeah,
ValueFromRemainingArgumentshas issues, see #2038mklement0 commentedon Aug 17, 2017
Pragmatically speaking:
I know we're talking about edge cases.
I know that I can avoid ambiguity by quoting.
That said, not having to quote constantly due to uncertainty over how barewords will be interpreted would be nice - after all, use of barewords is a perk of argument mode / shell-like syntax.
I'm not trying to be flippant when I say: Please do.
I'm honestly confused at this point, so if you can give a concise, comprehensive explanation of how
--prefixed barewords are meant to be handled in all scenarios - current bugs notwithstanding - based on rules people can actually keep in their heads, without needing to know how the parameter sausage is made, I'd personally appreciate it, but, as usual, documenting it for the world at large is the right thing to do.Also worth noting that PowerShell already has an unrelated bareword-rules complexity problem - see #3217
mklement0 commentedon Aug 17, 2017
P.S.: Let's not forget that when a
-<letter>-prefixed bareword does make it through as a value, it is not expanded the same way as non--prefixed bareword, as originally discussed in #4578:mklement0 commentedon Aug 20, 2017
I've taken a step back; please see #4624