我不明白使用begin / process / end blocks

时间:2015-05-01 15:10:29

标签: powershell

function Format-File {
  param(
    [Parameter(Mandatory = $true, Position = 0)]
    [ValidateNotNullOrEmpty()]
    [string] $path=$(throw "path is mandatory ($($MyInvocation.MyCommand))"),

    [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string] $key,

    [Parameter(Mandatory = $true, Position = 2, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string] $value
  )
}

我这样称呼它,假设我已经为字典添加了值(为了简洁而删除了)

$dict = New-Object 'System.Collections.Generic.Dictionary[string,string]'
$dict.GetEnumerator() | Format-File -Path $updatePath

这是我的难题。

以上工作完美。但是,以下没有,请注意键/值参数

的不同之处
function Format-File {
  param(
    [Parameter(Mandatory = $true, Position = 0)]
    [ValidateNotNullOrEmpty()]
    [string] $path=$(throw "path is mandatory ($($MyInvocation.MyCommand))"),

    [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string] $key=$(throw "key is mandatory ($($MyInvocation.MyCommand))"),

    [Parameter(Mandatory = $true, Position = 2, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string] $value=$(throw "value is mandatory ($($MyInvocation.MyCommand))")
  )
}

以上引发了异常。首次调用函数时,它似乎获取默认值,但在处理时,键/值参数设置正确。

为什么在函数调用时不设置键/值有点意义,但这也意味着我的心智模型已关闭。

所以我的问题是双重的。

  1. 这种性质的函数的参数绑定过程是什么,
  2. 如何验证从管道输入的值的输入?手动检查开始块,还是有其他方法?
  3. 如果您有更详细地描述这一切的链接,我很乐意阅读它。它让我意识到我的过程的心理模型是有缺陷的,我希望能解决这个问题。

1 个答案:

答案 0 :(得分:6)

这种性质的函数的参数绑定过程是什么?

Begin块中,管道绑定参数将为$null或使用默认值(如果有)。考虑到价值流水线还没有开始,这是有道理的。

Process块中,参数将是管道中的当前项目。

End块中,参数将是Process中的最后一个值,除非在验证参数时存在异常,在这种情况下它将使用默认值(或$null)。

如何验证从管道输入的值的输入?

您无法检查Begin阻止。

最好的方法是使用[Validate属性,就像使用[ValidateNotNullOrEmpty()]一样。

使用throw作为默认值的示例在某些情况下很有用,但它们是一种聪明的解决方法。问题是,你不需要它们,因为你已经将参数声明为Mandatory。

您可以使用[ValidateScript( { $value -eq 'MyString' } )]作为默认值,而不是使用默认值。

由于来自[ValidateScript()]的错误消息很糟糕,您可以将这些技术结合起来:

function Format-File {
  param(
    [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [ValidateScript( {
        ($_.Length -le 10) -or $(throw "My custom exception message")
    } )]
    [string] $key
  )
}

使用[ValidateScript()]无论是否为管道参数都可以使用。