I have a switch statement inside a function like so:
function SomeFunc {
[CmdletBinding()]
Param(
[Parameter(Position = 0)]
[switch]$History
)
Process {
switch ($PSBoundParameters.keys) {
'History' {$PSBoundParameters.keys}
Default {write-host "No Parameters used"}
}
}
}
If I invoke SomeFunc -History
"History" gets printed, as expected.
but for the life of me, I cannot get the default
condition to trigger, I am expecting "No Parameters used" to print when I invoke only "SomeFunc"
Any help on this would be really wellcome.
CodePudding user response:
tl;dr
Because
$PSBoundParameters.Keys
is an empty collection when no arguments are passed, theswitch
statement's body is never entered.Use
$PSBoundParameters.Count -eq 0
to detect if no parameters were passed.
It isn't obvious, but the switch
statement
enumerates its input, just like the pipeline does.
That is, if you provide an enumerable object to switch
, the enumerated elements are processed, one by one.
Typical examples of enumerables are arrays or collections, though not hashtables. See the bottom section of this answer for details on what PowerShell considers enumerable.
It follows that if there is nothing to enumerate, no processing takes place at all - not even the default
branch is entered.
In short: Any empty enumerable causes the switch
statement's body to be skipped, notably with:
an empty array or collection (one without elements), such as the empty
[System.Collections.Generic.Dictionary`2 KeyCollection[string, object]]
instance that the automatic$PSBoundParameters
variable's.Key
property returns when no parameters are bound.a call to a command that produces no output
- The reason is that PowerShell represents the no-output case with a special object sometimes called "AutomationNull", which can be thought of as an "enumerable
$null
"; that is, in an enumeration context it behaves like an empty collection rather than$null
- see this post for details.
- The reason is that PowerShell represents the no-output case with a special object sometimes called "AutomationNull", which can be thought of as an "enumerable
Two simple examples in which a switch
statement's body is skipped:
# An empty array has nothing to enumerate -> body is not entered.
switch (@()) {
default { 'Never get here!' }
}
# Ditto for a command that produces no output.
switch ((Get-ChildItem -Filter *NoSuchFiles*)) {
default { 'Never get here!' }
}