Written by

Lead Technical Analyst at Missouri Health Connection
Question Scott Beeson · 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"?

Comments

Timothy Leavitt · Feb 5, 2016

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

0
Scott Beeson  Feb 5, 2016 to Timothy Leavitt

Thanks for explaining the original issue.


As for the Prompt thing, can you explain the advantages of that over what I had?  What is $$$MatchArrayMask? It's not in the documentation.

0
Timothy Leavitt  Feb 5, 2016 to Scott Beeson

It is in the 2015.2 documentation (you linked to 2010.1):

$$$MatchArrayMask - Only entries from the array of options are allowed, not case sensitive

Update: It looks like it first showed up in 2013.1.

0
Scott Beeson  Feb 5, 2016 to Timothy Leavitt

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? http://docs.intersystems.com/cache20152/csp/docbook/DocBook.UI.Page.cls…

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

0
Ben Spead  Feb 5, 2016 to Scott Beeson

Scott - even though you may not have access to the SAMPLES namespace, you can still look at Caché samples.  Go to download.InterSystems.com and pull down a free single-user version of Caché and then you will have full access to everything that ships with Caché in your own local playspace ;)

0
Scott Beeson · Feb 5, 2016

Looking at the docs and it says "Handles prompting for chui applications."

What is CHUI?

0
Scott Beeson  Feb 5, 2016 to Timothy Leavitt

Oh, I call it a terminal! :)

0
Luca Ravazzolo · Feb 6, 2016

or COS CLI (Caché objectscript command line interface) :-o

0
Lexi Hayden · Feb 12, 2016

FWIW, having looked at the internals of a lot of our classes and routines, I have hardly ever come across GOTO.

0
Ben Spead · Feb 12, 2016

In fact, most COS programming guidelines that I have seen expressly forbid the use of GOTO since it makes the code harder to support.

0
Jorge de la Garza  Jan 10, 2017 to Ben Spead

One of the very first things I learned about programming as a wee lad taking Computer Science in high school is that GOTOs should be avoided, as they lead to what the textbook called "spaghetti code".

XKCD agrees, but for a different reason:

https://www.xkcd.com/292/

0
Lexi Hayden · Feb 12, 2016

Scott, another comment, if I may...

The best practice, in routines, is to use curly braces to define procedure blocks and thus control scope, e.g.

selecttype() {

stuff

}

dataentry() {

stuff

}

0
Scott Beeson  Feb 12, 2016 to Lexi Hayden

Yes, thank you, I have started doing that.

0
Scott Beeson  Mar 13, 2017 to John Murray

You're really trying to get those Global Masters points, aren't you?

0
John Murray  Mar 13, 2017 to Scott Beeson

Just trying to make the "no answer" view more useful...

0