What exactly is a PowerShell ScriptBlock

后端 未结 2 928
南旧
南旧 2021-02-07 20:37

A PowerShell ScriptBlock is not a lexical closure as it does not close over the variables referenced in its declaring environment. Instead it seems to leverage dynamic scope and

2条回答
  •  半阙折子戏
    2021-02-07 21:25

    Per the docs, a scriptblock is a "precompiled block of script text." So by default you just a pre-parsed block of script, no more, no less. Executing it creates a child scope, but beyond that it's as if you pasted the code inline. So the most appropriate term would simply be "readonly source code."

    Calling GetNewClosure bolts on a dynamically generated Module which basically carries a snapshot of all the variables in the caller's scope at the time of calling GetNewClosure. It is not a real closure, simply a snapshot copy of variables. The scriptblock itself is still just source code, and variable binding does not occur until it is invoked. You can add/remove/edit variables in the attached Module as you wish.

    function GetSB
    {
       $funcVar = 'initial copy'
    
       {"FuncVar is $funcVar"}.GetNewClosure()
    
       $funcVar = 'updated value'  # no effect, snapshot is taken when GetNewClosure is called
    }
    
    $sb = GetSB
    
    & $sb  # FuncVar is initial copy
    
    $funcVar = 'outside'
    & $sb  # FuncVar is initial copy
    
    $sb.Module.SessionState.PSVariable.Remove('funcVar')
    & $sb  # FuncVar is outside
    

提交回复
热议问题