· Feb 5, 2016

Difference between DO and GOTO in a macro procedure?

selecttype ; select gateway or ihe
     read "Deployment Type? (G)ateway or (I)HE: ", dtype

dataentry ; first data entry routine
     if (dtype="G") {
          set dtypeFull = "Gateway"
     elseif (dtype="I") {
          set dtypeFull = "IHE"
     else {
          write !,"Invalid Choice",!
          goto selecttype
     Write !, "Starting ", dtypeFull," deployment..."


This was what I first wrote.  Here is the test, first putting in an invalid value:

Deployment Type? (G)ateway or (I)HE: F
Invalid Choice
Deployment Type? (G)ateway or (I)HE: G
Starting Gateway deployment...


Then I saw this tutorial page where they call a method with "do".  So, I changed my "TODO" to a "DO".  Absolutely no other changes, now if I do the same test, here are the results:

Deployment Type? (G)ateway or (I)HE: F
Invalid Choice
Deployment Type? (G)ateway or (I)HE: G
Starting Gateway deployment...
Starting Gateway deployment...


Why does it output the last line twice with "DO"?

Discussion (19)0
Log in or sign up to continue

"GOTO label" jumps to a specified label in the same context frame.

"DO label" adds a new context frame. Code at the specified label will execute until a QUIT/RETURN or the end of the routine, then execution will resume at the next line after the DO command.

So in this case it's running through the whole routine (including everything under the dataentry label, with dtype already set to something valid), including printing the message at the end. Then it proceeds to the next thing after the DO command, which is printing that line again.

For what it's worth, if you're building command-line tools, %Library.Prompt may save you a lot of time. See the class reference for more informatioan.

For example:

#include %syPrompt
    New options,dtype
    Write "Deployment Utility"
    Set options(1) = "Gateway"
    Set options(2) = "IHE"
    Do ##class(%Prompt).GetArray("Deployment Type?",.dtype,.options,,,,$$$InitialDisplayMask+$$$MatchArrayMask)
    Write !, "Starting ", dtype," deployment..."

So I don't really understand the "context frame" thing.  Should I treat these like BATCH files or like OOP (Javascript, C#, VB, etc)?  Do you know of any good examples of routines?  I don't have access to the SAMPLES namespace.

edit: looks like this might be my answer?

But the "functions" have to be at the bottom?