A question of scope

I had a question left on my blog regarding scope.  The following is a simplified version of the problem

            
function level1 {            
 $iterations++            
 Write-Host '$iterations in level 1 = ' $iterations             
 level2            
}            
            
function level2 {            
 $iterations++            
 Write-Host '$iterations in level 2 =' $iterations            
}            
            
$iterations = 0            
            
Write-Host '$iterations at start =' $iterations            
level1            
            
Write-Host '$iterations at end =' $iterations

Start with a variable $iterations. Call a function and increment the variable. Call a nested function and increment the variable and then display the result

The output is

$iterations at start = 0
$iterations in level 1 =  1
$iterations in level 2 = 2
$iterations at end = 0

Start with zero, increment in level1 and level 2 – all OK. Show the final result & its zero.

The reason is scope.  Each of the functions has its own scope. Those scopes are destroyed – along with any variables & their contents when the functions finish.

If you want to keep the results then change to this

function level1 {            
 $global:iterations++            
 Write-Host '$global:iterations in level 1 = ' $global:iterations             
 level2            
}            
            
function level2 {            
 $global:iterations++            
 Write-Host '$global:iterations in level 2 =' $global:iterations            
}            
            
$global:iterations = 0            
            
Write-Host '$global:iterations at start =' $global:iterations            
level1            
            
Write-Host '$global:iterations at end =' $global:iterations

The output becomes

$global:iterations at start = 0
$global:iterations in level 1 =  1
$global:iterations in level 2 = 2
$global:iterations at end = 2

It is recommended not to use scopes in scripts if you can possibly avoid it – it can become very confusing in cases that are more complicated than this. The issue is better handled by passing parameters

function level1 {            
 param ($l1iterations)            
 $l1iterations++            
 Write-Host '$iterations in level 1 = ' $l1iterations            
 $l1iterations = level2 $l1iterations            
 $l1iterations            
}            
            
function level2 {            
param ($l2iterations)            
  $l2iterations++            
 Write-Host '$iterations in level 2 =' $l2iterations            
 $l2iterations            
}            
            
$iterations = 0            
            
Write-Host '$iterations at start =' $iterations            
$iterations = level1 $iterations            
            
Write-Host '$iterations at end =' $iterations

Much more on scope can be found in chapter 22 of my latest book PowerShell in Depth coauthored with Don Jones and Jeff Hicks –  http://www.manning.com/jones2/

This entry was posted in Powershell. Bookmark the permalink.

One Response to A question of scope

  1. cavallogolooso says:

    Reblogged this on Depresso Gioioso.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s