Wednesday, 8 August 2012

PowerShell - Did You Know - Scopes

You cannot depend on your eyes when your imagination is out of focus. - Mark Twain

I am a big fan of PowerShell, this is a rare occasion that Microsoft gets something right. If you want to learn more about PowerShell I suggest you buy this really great book or follow this blog. I thought I would start a series that outline some interesting and wonderful things I find about the language.

Today one of my colleges at work asked a very wonderful question about scopes, which left me puzzled (he is a JavaScript guru so I didn't understand why he didn't get it ;)

If you read through the official documentation about scopes you might get a bit confused like I did.

    Local:  
        The current scope. The local scope can be the global 
        scope or any other scope. -- Hmmm

As we can see from the documentation PowerShell does not mention a concept of function scope like in JavaScript. If we take the JavaScript example and turn it into PowerShell we might get a surprise
$sport = "baseball"
$player = $null

function Get-Player() {
    if ($sport -eq "baseball") {  
        $player = "Evan Longoria"; # (the baseball player)  
    } 
    else {  
        $player = "Eva Longoria"; # (the actress)  
    }

    $player2 = "Derek Jeter";  
    return $player;
}

Get-Player
Write-Host $player
The $player variable is still $null. Not what I expected. However if we define a function within a function then the variable is available in the inner scope.
$sport = "baseball"
$player = $null

function Get-Player() {
    if ($sport -eq "baseball") {  
        $player = "Evan Longoria"; # (the baseball player)  
    } 
    else {  
        $player = "Eva Longoria"; # (the actress)  
    }

    $player2 = "Derek Jeter";  

    function Inner-Function {
        Write-Host $player
        Write-Host $player2
    }

    Inner-Function

    return $player;
}

Get-Player
If we prefix the $player2 variable with $script it is now in scope.
$sport = "baseball"
$player = $null

function Get-Player() {
    if ($sport -eq "baseball") {  
        $player = "Evan Longoria"; # (the baseball player)  
    } 
    else {  
        $player = "Eva Longoria"; # (the actress)  
    }

    $script:player2 = "Derek Jeter";  
    return $player;
}

Get-Player
Write-Host $player2
Another interesting example is
$sport = "baseball"
$player = $null

function Get-Player() {
    if ($sport -eq "baseball") {  
        $player = "Evan Longoria"; # (the baseball player)  
    } 
    else {  
        $player = "Eva Longoria"; # (the actress)  
    }

    $player2 = "Derek Jeter";

    Print-Player
    
    return $player;
}

function Print-Player {
    Write-Host $player2
}

Get-Player
The variable $player2 is defined in Print-Player. 

I hope that you find this as interesting as I have. Make sure you tune in to the next episode of PowerShell - Did You Know