Home > Net >  Powershell - variable scope in function and loop
Powershell - variable scope in function and loop

Time:10-19

Consider the following:

function GetOneOf($prompt, $values) {
    $response=
    while ($response -eq $null) {
        $response = read-host $prompt
        if ( -not ($values -icontains $response)) {
            $response = $null
        }
    }
    $response
}

function GetOneOfV2($prompt, $values) {
    # "$response=" fragment is missing
    while ($response -eq $null) {
        $response = read-host $prompt
        if ( -not ($values -icontains $response)) {
            $response = $null
        }
    }
    $response
}

$resp = GetOneOf 'enter A or B' 'a', 'b'
write-host "RESP: $resp"
$resp = GetOneOfV2 'enter A or B' 'a', 'b'
write-host "RESP: $resp"

Why GetOneOf does not return entered value and GetOneOfV2 returns it? I don't see any reason for this to work this way. If the first case (GetOneOf) works this way because while constitutes another scope and variable can't be changed there then OK, but if so then in second case there should be no way to read value of $response in scope outside loop because there was no such variable earlier. In fact I should get no such variable or similar error. But if we assume that changes inside loop are visible on the outside (second case) and they even make variable available to outer scope, then how is it possible that first case does not work?

And also how can I make first case (GetOneOf) work?

I use the following:

Name                           Value
----                           -----
PSVersion                      5.1.19041.1237
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.1237
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

CodePudding user response:

It is nothing related to variable scopes, you are assigning the return value of while to $response, which is always null because you return nothing.

Here this should work:

function GetOneOf($prompt, $values) {
    $response=
    while ($response -eq $null) {
        $response = read-host $prompt
        if ( -not ($values -icontains $response)) {
            $response = $null
        } else {
            echo $response
        }
    }
    $response
}

Output:

PS C:\> $resp = GetOneOf 'enter A or B' 'a', 'b'
enter A or B: d
enter A or B: f
enter A or B: g
enter A or B: w
enter A or B: a
PS C:\> $resp
a
PS C:\> $resp.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
  • Related