从不同范围引用当前对象

时间:2017-07-27 11:22:23

标签: powershell scoping

我希望能够从catch块中调用的函数中引用catch块中的$_对象,如下所示:

function foo
{
    $something = ((Get-Variable -Name "_" -Scope 1).Value).Exception.Message
    Write-Host $something
}

我想在以下情况下使用它:

foo #write-host should print empty line
try {
    throw
} catch {
    foo #write-host should print $_.Exception.Message from this catch block
}

如何正确地做到这一点? 我的目标是避免每次在catch块中使用$_作为参数传递给foo,而当我调用foo而不是在catch块中时,不要打印任何内容。

我也试过这个:

function foo
{
    $something = (($ExecutionContext.SessionState.PSVariable.Get("_")).Value).Exception.Message
    Write-Host $something
}

这似乎在交互式工作时产生了我想要的结果,但在启动脚本时却没有。

1 个答案:

答案 0 :(得分:2)

clean 这样做的方式当然是foo上的(可选)参数,来自foo $_块的catch调用。这使我们非常清楚我们正在调用foo的内容,它与范围界定没有问题,它使foo可测试,所有这些都很好。您将在大多数打印错误的内容中看到此方法(例如,在this question的答案中)。

即便如此,如果你坚持从父框架中提取错误变量,可以这样做:

function foo {
    $lastError = (Get-PSCallStack)[1].GetFrameVariables()["_"].Value
    if ([Object]::ReferenceEquals($lastError.Exception, $error[0].Exception)) {
        $lastError.Exception.Message
    }
}

注意Object.ReferenceEquals的额外诡计是绝对确定$_是指最后一个错误记录而不是某个任意管道项(也使用$_)。如果错误记录本身在管道中(例如$error |% { foo }),这将仍然失败,但此时您也可以称之为功能。