Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell - execute script block in specific scope

I am trying to implement RSpec/Jasmine like BDD framework in Powershell (or at least research the potential problems with making one).

Currently I am having problems with implementing simple before/after functionality. Given

$ErrorActionPreference = "Stop"

function describe()
    {
    $aaaa = 0;
    before { $aaaa = 2; };
    after { $aaaa; }
    }

function before( [scriptblock]$sb )
    {
    & $sb
    }

function after( $sb )
    {
    & $sb
    }

describe

the output is 0, but I would like it to be 2. Is there any way to achieve it in Powershell (short of making $aaaa global, traversing parent scopes in script blocks till $aaaa is found, making $aaaa an "object" and other dirty hacks:) )

What I would ideally like is a way to invoke a script block in some other scope but I don't have a clue whether it is possible at all. I found an interesting example at https://connect.microsoft.com/PowerShell/feedback/details/560504/scriptblock-gets-incorrect-parent-scope-in-module (see workaround), but am not sure how it works and if it helps me in any way.

TIA

like image 819
mbergal Avatar asked Jul 29 '12 07:07

mbergal


1 Answers

The call operator (&) always uses a new scope. Instead, use the dot source (.) operator:

$ErrorActionPreference = "Stop"

function describe()
    {
    $aaaa = 0;
    . before { $aaaa = 2; };
    . after { $aaaa; }
    }

function before( [scriptblock]$sb )
    {
    . $sb
    }

function after( $sb )
    {
    . $sb
    }

describe

Note the use of . function to invoke the function in same scope as where `$aaaa is defined.

like image 92
x0n Avatar answered Oct 10 '22 12:10

x0n