Parameters with default value not in PsBoundParameters?

左心房为你撑大大i 提交于 2019-12-08 16:04:35

问题


General code

Consider this code:

PS> function Test { param($p='default value') $PsBoundParameters }
PS> Test 'some value'
Key                                                               Value
---                                                               -----
p                                                                 some value
PS> Test
# nothing

I would expect that $PsBoundParameters would contain record for $p variable on both cases. Is that correct behaviour?

Question

I'd like to use splatting that would work like this for a lot of functions:

function SomeFuncWithManyRequiredParams {
  param(
    [Parameter(Mandatory=$true)][string]$p1,
    [Parameter(Mandatory=$true)][string]$p2,
    [Parameter(Mandatory=$true)][string]$p3,
  ...other parameters
  )
  ...
}
function SimplifiedFuncWithDefaultValues {
  param(
    [Parameter(Mandatory=$false)][string]$p1='default for p1',
    [Parameter(Mandatory=$false)][string]$p2='default for p2',
    [Parameter(Mandatory=$false)][string]$p3='default for p3',
  ...other parameters
  )
  SomeFuncWithManyRequiredParams @PsBoundParameters
}

I don't want to call SomeFuncWithManyRequiredParams with all the params enumerated:

  SomeFuncWithManyRequiredParams -p1 $p1 -p2 $p2 -p3 $p3 ...

Is it possible?


回答1:


It depends on how you define "bound" I guess i.e. is the value bound from a user supplied value or a default value supplied by the function? Honestly, it doesn't surprise me that it behaves the way it does as I view "bound" to mean the former - bound from user input. Anyway, you can solve this by patching the $PSBoundParameters variable e.g.:

function SimplifiedFuncWithDefaultValues { 
  param( 
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
  ...other parameters 
  ) 
  if (!$PSBoundParameters.ContainsKey(p1))
  {
    $PSBoundParameters.p1 = 'default for p1'
  }
  # rinse and repeat for other default parameters.
  SomeFuncWithManyRequiredParams @PSBoundParameters 
} 



回答2:


I know this question is very old, but I had a need for something like this recently (wanted to do splatting with a lot of default parameters). I came up with this and it worked very well:

$params = @{}
foreach($h in $MyInvocation.MyCommand.Parameters.GetEnumerator()) {
    try {
        $key = $h.Key
        $val = Get-Variable -Name $key -ErrorAction Stop | Select-Object -ExpandProperty Value -ErrorAction Stop
        if (([String]::IsNullOrEmpty($val) -and (!$PSBoundParameters.ContainsKey($key)))) {
            throw "A blank value that wasn't supplied by the user."
        }
        Write-Verbose "$key => '$val'"
        $params[$key] = $val
    } catch {}
}

Shameless plug ahead: I decided to turn this into a blog post which has more explanation and a sample usage script.




回答3:


You could use a helper function similar to the Add-Variable function below:

function SimplifiedFuncWithDefaultValues {
    param(
        [Parameter(Mandatory=$false)][string]$p1='default for p1',
        [Parameter(Mandatory=$false)][string]$p2='default for p2',
        [Parameter(Mandatory=$false)][string]$p3='default for p3',
        ...other parameters
    )

    $PSBoundParameters | Add-Variable p1, p2, p3

    SomeFuncWithManyRequiredParams @PSBoundParameters 
}

function Add-Variable {
    param(
        [Parameter(Position = 0)]
        [AllowEmptyCollection()]
        [string[]] $Name = @(),
        [Parameter(Position = 1, ValueFromPipeline, Mandatory)]
        $InputObject
    )

    $Name |
    ? {-not $InputObject.ContainsKey($_)} |
    % {$InputObject.Add($_, (gv $_ -Scope 1 -ValueOnly))}
}



回答4:


This is what I like to do:

foreach($localP in $MyInvocation.MyCommand.Parameters.Keys)
{
    if(!$PSBoundParameters.ContainsKey($localP))
    {
        $PSBoundParameters.Add($localP, (Get-Variable -Name $localP -ValueOnly))
    }        
}


来源:https://stackoverflow.com/questions/2808973/parameters-with-default-value-not-in-psboundparameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!