2017-07-27 55 views
0

参照当前对象我希望能够提及$_对象在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 
} 

这似乎产生交互工作时,但不能启动脚本时,我想要的结果。

+0

有一个全局'$ error'变量。 '$ error [0]'保存遇到的最后一个错误。 –

+0

它是全局的事实在调用“foo”不在catch块中时会产生不想要的结果,在这种情况下,我不希望它返回它从上一个catch块中保存的最后一个错误。 –

+0

坦率地说,我会给'foo()'一个默认值为'$ null'的参数,并在catch块中调用'foo $ _'。仅当参数的类型为[[Management.Automation.ErrorRecord]'时才输出异常消息。 –

回答

2

这样做的清洁方式,当然,在foo(可选的)参数,从catch块调用foo $_。这使得它完全清楚我们要求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 }),这将使仍然失败,但此时您可能称之为功能。