Home > Blockchain >  Assigning return value to variable breaks recursion
Assigning return value to variable breaks recursion

Time:03-08

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

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.

  • Related