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