Question
· Sep 30, 2017

Passing an array to a class method on a job command

hi-

Can someone give me an example of how to JOB a class method that requires an array of values to be passed to it by reference.  

This is what I tried, but am getting compile errors because of the .params

job ##class(%SYSTEM.OBJ.FM2Class).All(.params)::5

Any thoughts on how to accomplish this, the simplest way.  I would like to avoid writing all of this to some global and having to write some wrapper to pick it up and then call the class method, which I certainly could do.  but is this the only way to do it?

Discussion (9)2
Log in or sign up to continue

Thanks Robert-

I dont think I have a choice here.  the All method of the %SYSTEM.OBJ.FM2Class expects the array to be passed by reference.  I did come up with a solution though....

/// Run FM2Class in background fo rnewly created namespace

ClassMethod ConfigFM2Class(Namespace As %String, LocalPath As %String) As %String
{
new $namespace set curnsp=$namespace,$namespace=Namespace
write !,"Starting FM2Class for Namespace ",Namespace," in background"
; Build Up Parameters
set params("childTableNameFormat")="SUB_<FILENAME>,<FILENUMBER>"
    set params("compile")=1
    set params("compileQSpec")="/display=all/lock=0"
    set params("dateType")="%Library.FilemanDate"
    set params("datetimeType")="%Library.FilemanTimeStamp"
    set params("deleteQSpec")="/display=all"
    set params("display")=0
    set params("expandPointers")=0
    set params("expandSetOfCodes")=0
    set params("extendedMapping")=""
    set params("fieldNameFormat")="Exact"
    set params("ienFieldName")="IEN"
    set params("logFile")=LocalPath_"fm2class_"_Namespace_".log"
    set params("nameLength")=180
    set params("owner")="_SYSTEM"
    set params("package")="VISTA"
    set params("readonly")=0
    set params("recursion")=2
    set params("requiredType")=0
    set params("retainClass")=1
    set params("setOfCodesEnum")=1
    set params("strictData")=0
    set params("superClasses")=""
    set params("tableNameFormat")="<FILENAME>,<FILENUMBER>"
    set params("variablePointerValueField")=0
    set params("wpIsList")=0
    kill ^UTILITY(Namespace,$j,"ISC.HealthConnect.Installer") merge ^UTILITY($j,"ISC.HealthConnect.Installer")=params
    set $namespace=curnsp
    job ##class(ISC.HealthConnect.Installer).jobfm(Namespace,$j)::5
set zSC=1
if '$t set zSC=0
quit zSC
}
ClassMethod jobfm(Namespace,job)
{
;Startup FM2Class
new $namespace set $namespace=Namespace
merge params=^UTILITY(job,"ISC.HealthConnect.Installer")
kill ^UTILITY(job,"ISC.HealthConnect.Installer")
do ##class(%SYSTEM.OBJ.FM2Class).All(.params)
quit

}

It's better to use CACHETEMP mapped global, e.g. ^CacheTempUserYourGlobal($job,...).

BTW there is another option: having a wrapper job, pass it an array serialized to JSON, other steps are evidient. I used it in one of my projects, and it was quicker than using of ^CacheTemp* intermediate global, while performance gain was not too sufficient (AFAIR)

The approach with a global is apparently easier, so I'd use it if performance would not of great importantance.

For passing array by reference try to use the class $system.WorkMgr instead of job.

Sample:

Class demo.test Abstract ]
{

ClassMethod Test(arrayAs %Status
{
  ^CacheTempUser.dbg
  ^CacheTempUser.dbg($zp)=array
  ^CacheTempUser.dbg($zp,"$j")=$j
  q $$$OK
}

}

demo()
  queue,arr

  arr(1)="qwe"
  arr(2)="asd"
  
  "$j = ",$j,!
  queue=$system.WorkMgr.Initialize("/multicompile=1",,1)
  queue.Queue("##class(demo.test).Test",.arr)
  queue.WaitForComplete()
  
  zw ^CacheTempUser.dbg
  q

Result:

USER>^demo
$j = 7600
^CacheTempUser.dbg(8488,1)="qwe"
^CacheTempUser.dbg(8488,2)="asd"
^CacheTempUser.dbg(8488,"$j")=8348