I'm working on a recursive function to compare two JSON objects and ran into a strange issue. My recursion works fine... until I assign the result of the recursive call to a variable. If I just make the function call, the recursion works, and all members are iterated. When the assignment is present, recursion breaks and only the first level of the object is iterated.
(Line with arrow indicates recursive call)
Is there some reason this doesn't work?
function Compare-Objects() {
[CmdletBinding()]
Param(
$Current,
$Expected
)
foreach ($Property in $Expected.PSObject.Properties) {
$Property.Name " : " $Property.TypeNameOfValue
if ($Property.TypeNameOfValue -like "*PSCustomObject") {
-> $Match = Compare-Objects -Current $Current.$($Property.Name) -Expected $Expected.$($Property.Name)
}
elseif ($Property.TypeNameOfValue -like "*Object[[][]]"){
# Compare-Arrays -Current $Current.$($Property.Name) -Expected $Expected.$($Property.Name)
}
else {
if ($Property.Value -like "*enums*") {
$Expected.$($Property.Name) = Invoke-Expression -Command $Expected.$($Property.Name)
}
if ($Current.$($Property.Name) -ne $Expected.$($Property.Name)) {
return $false
}
}
}
return $true
}
CodePudding user response:
A side effect of using a variable assignment ($Match = ...
) is that the value being assigned is no longer subject to PowerShell's implicit output behavior, i.e. it isn't emitted to the statement's / function's / script [block]'s success output stream and thereby no longer contributes to its "return value".
In other words: your recursion worked fine, you just accidentally suppressed output from nested calls.
If you want to assign command output to a variable and pass the assigned value through to the success output stream, enclose it in (...)
, i.e, use ($Match = ...)
Separately, if you want to bypass the success output stream, e.g. for printing status / debugging information that doesn't interfere with data output:
You can write to PowerShell's other output streams, with cmdlets such as
Write-Verbose
andWrite-Debug
, which produce visible output only if requested.By contrast, the
Write-Host
cmdlet - primarily intended for to-display output, often including formatting (coloring) - produces visible output by default.
CodePudding user response:
It turns out this didn't break my recursion... this is just me forgetting PowerShell's behavior of consuming output when there is an assignment.
Basically, I was looking for my debugging text two lines above the recursive call and it wasn't appearing. Adding Write-Host
to the debugging line made the output appear again.