Thatās not quite the same, as the purpose of #INVOKE is rather special.
Letās start with #INSERT and #CALL, which are more similar to each other:
#INSERT is the traditional command, and indicates to generate the named group with its code left-justified at the column position of the #INSERT. For example, if the #INSERT is position in column 5, then the #GROUP code will appear in column 5. If the code in the #GROUP itself is indented, then that will be added to the #INSERT column position. You can disable this indentation with the NOINDENT attribute.
#CALL was added later. It can call a #GROUP like #INSERT, but the generated group code will ignore the column position of #CALL, like #INSERT(...),NOINDENT.
Generally speaking, I use #INSERT to call a #GROUP that I expect to generate code, while I use #CALL to execute a #GROUP that contains pure logic (no generated code). I break that rule occasionally, mostly when I use #INSERT in place of #CALL (because it was always OK to use #INSERT).
With both #INSERT and #CALL, the name of the #GROUP must be hard-coded when the template is written:
#INSERT(%SomeGroup) #!Generates code starting at column 3
#CALL(%SomeGroup) #!Generates code started at column 1
#CALL can also be used to call a #GROUP that returns a value (although I believe they added that ability to #INSERT as well):
#DECLARE(%CapturedReturnValue)
#CALL(%SomeGroup), %CapturedReturnValue
#INVOKE is different in a very important way. Itās used to call a #GROUP, where the name isnāt known until the code is generated (long after the template was written). You have to assign the name of the #GROUP to a runtime symbol, then pass that symbol to the #INVOKE command:
#EQUATE(%SomeGroupName, '%SomeGroup(ABC)')
#INVOKE(%SomeGroupName)
#INVOKE can also specify a return value be captured.
I believe the chain name is optional with all of them. Parameters are passed the same for all three commands.
Bottom line, hereās how I choose to use them:
- If the
#GROUP Iām calling will generate code, I use #INSERT.
- If ifās pure logic with no generated code, I use
#CALL.
- If I donāt know the name of the
#GROUP until generation time (very special), then I use #INVOKE.
FYI, I have only two instances of #INVOKE in all of my template sets. Itās typically used to generate virtual methods based upon reading of classes at generation time.