How to get output of ZZDUMP into a variable

Primary tabs

Using ZZDUMP command in  terminal is a nice debugging feature.

But it is useless in background jobs.

How can I get the output into a variable or - less attractive - in a stream object ?

Replies

Hm, I don't understand why do you need to do zzdump in background? I would just log to debug globals any variables / expressions I need. And later, when doing output, I would zzdump them.

the most simple solution could be the use of Device 2 (SPOOL) that moves the output into ^SPOOL Global

USER>set value=123.44_"€"

  USER>zzdump value 
  0000: 0031 0032 0033 002E 0034 0034 20AC                      123.44€

  USER>open 2:0 use 2 zzdump value close 2

  USER>zw ^SPOOL(0)
  ^SPOOL(0,1)=$c(13,10)
  ^SPOOL(0,2)="0000: 0031 0032 0033 002E 0034 0034 20AC                        123.44€"
  ^SPOOL(0,2147483647)="{65203,502{3{"USER>

  USER>write ^SPOOL(0,2)
  0000: 0031 0032 0033 002E 0034 0034 20AC                      123.44€
  USER>

Source code of ZZDUMP is available in ISCzzdump.INC

I've redone it a bit for your needs:

  #include %syGluedef
  n

  s value=123.44_"€"
  zzdump value

  zzdump2array(value,.arr)
  !!
  zw arr

zzdump2array(x,&arr) public Ztrap:'$D(x$$$APPERROR($$$ERSYNTXSet $ZT="zzderr"
  #; c is number of characters per line
  #; d is number of hexadecimal digits per character code
  If $ZISWIDE(xSet c=8,d=4 Else Set c=16,d=2 }
  Set arr=0
  For i=0:c:$Length(x)-1 {
    Set s=$Extract(x,i+1,i+c),n=$Length(s)
    Set arr=arr+1
    Set v=$TR($J($ZHEX(i),4)," ","0")_": "
    For j=1:1:{
      Set v=v_$TR($J($ZHEX($A(s,j)),d)," ","0")_" "
      Set:$E(s,j)?1$E(s,j)="."
    }
    Set v=v_$JUSTIFY("",62-$LENGTH(v))_s
    Set arr(arr)=v
  }
  Quit
zzderr Set $ZT="" Ztrap $$$APPERROR($$$LASTERROR)
}

USER>^test
 
0000: 0031 0032 0033 002E 0034 0034 20AC                      123.44€
 
arr=1
arr(1)="0000: 0031 0032 0033 002E 0034 0034 20AC                      123.44€"

LOG^%ETN would be much better, but too heavy and very slow.

But if saying about a debug global, it is suitable only for simple data, not for objects.

It's for producing a trace protocol in background triggered by task manager

A very nice and clean implementation of the principle!

Great job.

It was more for informational purposes. But you can always change something, such as the output format.

Here is another option how to redirect the output to a variable, global, stream, etc. (suddenly someone come in handy):

  #include %systemInclude
  #include %callout
  n
  s value=123.44_"€"
  zzdump value
  
  !,$$anywrite2quit("zzdump value")

anywrite2quit(command) public {
  Try{
    Set tIO=$IO,tXDEV="|XDEV|"_+$Job
    Do {
      
      // For $$$IsUnicode use UTF-8
      Open tXDEV:($ZF(-6,$$$XSLTLibrary,12):"":"S":/HOSTNAME="XSLT":/IOT=$Select($$$IsUnicode:"UTF8",1:"RAW"):/IBU=16384:/OBU=16384)
      Use tXDEV
      
      Xecute command
      
      // Flush any remaining output
      Write *-3
      
      // Now read back a string (up to the maximum possible length, 32k or ~4MB for long strings)
      Set ""
      While (1) {
        #Dim tChunk As %String
        Read tChunk:0
        Quit:'$Length(tChunk)
        Set tChunk
      }
      
    } While (0)
  }Catch{}

  Close tXDEV
  Use tIO
  Quit s
}