Written by

~~ retired but not tired ~~
MOD
Article Robert Cemper · Oct 21, 2025 2m read

Practical use of XECUTE (InterSystems ObjectScript)

If you start with InterSystems ObjectScript, you will meet the XECUTE command.
And beginners may ask: Where and Why may I need to use this ?

The official documentation has a rich collection of code snippets. No practical case.
Just recently, I met a use case that I'd like to share with you.

The scenario:

When you build an IRIS container with Docker, then, in most cases,
you run the  initialization script  

iris session iris < iris.script 

This means you open a terminal session and feed your input line-by-line from the script.
And that's fine and easy if you call methods, or functions, or commands.
But looping over several lines is not possible.
You may argue that running a FOR loop in a line is not a masterpiece.
Right, but the lines are not endless and the code should remain maintainable.

A different goal was to leave no code traces behind after setup.
So iris.script was the location to apply it.

The solution

XECUTE allowed me to cascade my multi-line code.
To avoid conflicts with variable scoping, I just used %Variables 
BTW: The goal was to populate some demo LookupTables.
Just for comfort, I used method names from %PopulateUtils as table names

   ;; generate some demo lookup tables   
   ; inner loop by table
    set %1="for j=1:1:5+$random(10) XECUTE %2,%3,%4"
    ; populate with random values
    set %2="set %key=##class(%PopulateUtils).LastName()"
    set %3="set %val=$ClassMethod(""%PopulateUtils"",%tab)"
    ; write the table
    set %4="set ^Ens.LookupTable(%tab,%key)=%val"
    set %5="set ^Ens.LookupTable(%tab)=$lb($h) write !,""LookupTable "",%tab"
    ; main loop
    XECUTE "for %tab=""FirstName"",""City"",""Company"",""Street"",""SSN"" XECUTE %1,%5"
    ;; just in Docker

The result satisfied the requirements without leaving permanent traces behind 
And it did not interfere with the code deposited in IPM.
So it was only used once by Docker container build.
 

Comments

Marcelo Witt · Jun 15

Many years ago I used Xecute in some very specific situations that, I confess, I don't even remember very well anymore; however, I remember very well that debugging legacy code is always made more difficult with the use of Xecute, so I have always been an advocate against using it, except in situations of extreme necessity. 
But I recognize that in your example it really seemed quite useful.

0
Rob Dewan · Jun 15

Howdy, Robert! 

I'm another Rob(ert) and I've been a longtime reader (and fan) of your posts here in the developer community. Thank you for elucidating this use case of XECUTE, I have not considered using this command in a here-document before and I admire your approach! I would also like to share some of the workarounds that I've used in the past to approach similar problems:

Escape newline characters in your here-document:

var="InterSystems"
irissession MYIRIS -U%SYS<<EOF
FOR i=1:1:10 {\
  W i,!\
}
W !,"Howdy, $var!",!
H
EOF

Split your string and join it on a space (easiest to use in perl and python IMHO):

import subprocess

# Let's interpolate a variable
var = "InterSystems"

# Build iris_cmd
iris_cmd = f"""
FOR i=1:1:10 {{
    W i,!
}}
W !,"Howdy, {var}!",! 
H
"""

# write one-big line
iris_cmd = ' '.join(iris_cmd.split()) +"\n"

# Run commands in an irissession
proc = subprocess.run(
    ['irissession', 'IRISHEALTH', '-U', '%SYS'],
    input=iris_cmd,
    check=True,
    capture_output=True,
    text=True
)

for line in proc.stdout.splitlines():
    print(line)

Have your here-document write a routine and execute it:

cls="Config.Databases"
mthd="ListFunc"
irissession MYIRIS -U%SYS<<EOF
ZI "zExecute(cls,mthd);"
ZI "  S rset=\$CLASSMETHOD(cls,mthd)"
ZI "  WHILE (rset.%Next()) {"
ZI "    W rset.Name,?20,rset.Directory,!"
ZI "  }"
D zExecute("$cls","$mthd")
H
0
Robert Cemper  Jun 19 to Rob Dewan

Thank you, Rob for your example. (Somewhat late as I was offline this week)!

I like the idea to use a series of ZI  with no  ZSAVE is great.
Similar to run some external code using $CLASSMETHOD()
a perfect solution

🙂

0