Некоторая предыстория: когда пустой конвейер назначается переменной, значение равно [System.Management.Automation.Internal.AutomationNull]::Value
, как описано здесь https://stackoverflow.com/a/22365076/37572
AutomationNull обладает некоторыми интересными свойствами.
- AutomationNull -eq $null
- AutomationNull -is [psobject]
- если AutomationNull передается в функцию ($x), то значение аргумента $x является простым $null
Код ниже присваивает AutomationNull члену массива, а затем вызывает функцию f($x) с массивом в качестве аргумента. Удивительным результатом является то, что член массива, который раньше содержал AutomationNull, теперь содержит простой $null.
"PSVersion "+ $PSVersionTable.PSVersion
Write-Host -ForegroundColor Yellow "******** array initialized"
$array = @(0,$null,2)
for($i=0; $i -lt $array.Count; $i++) {
if ($null -eq $array[$i]) {
if ($array[$i] -is [psobject]) {"array[$i] is null and [psobject]"
} else {"array[$i] is null"}
} else {"array[$i] is " + $array[$i]}
}
Write-Host -ForegroundColor Yellow "******** array[1] set to empty pipeline"
$emptypipe = (@()|%{1})
$array[1] = $emptypipe
for($i=0; $i -lt $array.Count; $i++) {
if ($null -eq $array[$i]) {
if ($array[$i] -is [psobject]) {"array[$i] is null and [psobject]"
} else {"array[$i] is null"}
} else {"array[$i] is " + $array[$i]}
}
function f($x) {Write-Host -ForegroundColor Yellow '******** called: f -x $array'}
f -x $array
for($i=0; $i -lt $array.Count; $i++) {
if ($null -eq $array[$i]) {
if ($array[$i] -is [psobject]) {"array[$i] is null and [psobject]"
} else {"array[$i] is null"}
} else {"array[$i] is " + $array[$i]}
}
Полученные результаты:
PSVersion 3.0
******** array initialized
array[0] is 0
array[1] is null
array[2] is 2
******** array[1] set to empty pipeline
array[0] is 0
array[1] is null and [psobject]
array[2] is 2
******** called: f -x $array
array[0] is 0
array[1] is null
array[2] is 2
Таким образом, кажется, что простой вызов f($x) с массивом в качестве аргумента изменил содержимое массива.
Сам по себе я согласен, что это странный пограничный случай, но, похоже, это пример довольно простого предположения, нарушаемого языком.
Кто-нибудь может объяснить такое поведение?
P.S. Извините, что приведенный выше код должен дословно повторять цикл for три раза, но превращение его в функцию скрывает фактический результат теста.