1

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
}
Jonathon Anderson
  • 1,162
  • 1
  • 8
  • 24

1 Answers1

3

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 and Write-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.

mklement0
  • 382,024
  • 64
  • 607
  • 775