Ответ 1
Вы действительно тестируете здесь две вещи, существование и ценность. И тест существования является тем, который вызывает предупреждения в режиме строгого режима. Итак, отделите тесты. Помня, что PowerShell рассматривает переменные как просто еще один поставщик (как и файл или поставщик реестра) и что все переменные PowerShell существуют как файлы в корневой папке диска с именем "variable:", становится очевидным, что вы можете использовать тот же механизм, что и вы обычно использовали бы для проверки любого другого существования файла. Следовательно, используйте "тестовый путь":
if (!(test-path variable:\var)) {$var = $null} # test for EXISTENCE & create
if ( !$var ) { $var = "new-value"; } # test the VALUE
Обратите внимание, что текущий строгий режим может быть изменен в дочерних областях без влияния на родительскую область (например, в script -блоках). Таким образом, вы можете написать блок script, который инкапсулирует удаление строгого режима и настройку переменной, не влияя на строгость окружающей программы. Это немного сложно из-за переменной области видимости. Две возможности, о которых я могу думать:
# 1 - вернуть значение из блока script
$var = & { Set-StrictMode -off; switch( $var ) { $null { "new-value" } default { $var } }}
или # 2 - используйте модификаторы области действия
& { Set-StrictMode -off; if (!$var) { set-variable -scope 1 var "new-value" }}
Вероятно, самая худшая из них - это склонное к ошибкам повторное использование $var (как с ведущим, так и без него). Это кажется очень склонным к ошибкам. Поэтому вместо этого я использую подпрограмму:
function set-Variable-IfMissingOrNull ($name, $value)
{
$isMissingOrNull = !(test-path ('variable:'+$name)) -or ((get-variable $name -value) -eq $null)
if ($isMissingOrNull) { set-variable -scope 1 $name $value }
}
set-alias ?? set-Variable-IfMissingOrNull
#...
## in use, must not have a leading $ or the shell attempts to read the possibly non-existant $var
set-VarIfMissingOrNull var "new-value"
?? varX 1
Последнее, вероятно, похоже на то, что я script его.
РЕДАКТИРОВАТЬ: Подумав о вашем вопросе немного дольше, я придумал более простую функцию, которая более точно соответствует вашему стилю кодирования. Попробуйте эту функцию:
function test-variable
{# return $false if variable:\$name is missing or $null
param( [string]$name )
$isMissingOrNull = (!(test-path ('variable:'+$name)) -or ((get-variable -name $name -value) -eq $null))
return !$isMissingOrNull
}
set-alias ?-var test-variable
if (!(?-var var)) {$var = "default-value"}
Надеюсь, что это поможет.