PowerShell - как проверить значение переменной с помощью "Set-StrictMode -version latest"?

Я только что начал создавать скрипты PowerShell, и я столкнулся с проблемой тестирования переменных для значения. Я пытаюсь запустить все с включенными предупреждениями, особенно во время обучения, чтобы уловить глупые ошибки. Итак, я использую CTPV3 и устанавливаю строгий режим с помощью "set-strictmode -version latest". Но я столкнулся с дорожным блоком, проверяя входящие переменные на значение. Эти переменные могут быть или не быть уже установлены.

# all FAIL if $var is undefined under "Set-StrictMode -version latest"
if ( !$var ) { $var = "new-value"; } 
if ( $var -eq $null ) { $var = "new-value"; } 

Я не могу найти способ проверить, имеет ли переменная значение, которое не вызывает предупреждения, когда переменная отсутствует, если я не отключу строгий режим. И я не хочу включать и выключать строгий режим, чтобы проверить переменные. Я уверен, что я забуду вернуть его где-нибудь, и это выглядит ужасно загроможденным. Это не так. Что мне не хватает?

Ответы

Ответ 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"}

Надеюсь, что это поможет.

Ответ 2

Во-первых, я люблю ответ Роя, полный и краткий. Я просто хотел упомянуть, что кажется, что вы пытаетесь установить только переменную, если она уже установлена. Это похоже на работу для переменных только для чтения или констант.

Чтобы сделать переменную только для чтения, константа, используйте

Set-Variable

От get-help Set-Variable -full

-- ReadOnly: Cannot be deleted or changed without the Force parameter.
-- Constant: Cannot be deleted or changed. Constant is valid only when
creating a new variable. You cannot set the Constant option on an
existing variable.