What is the difference between #Call & #Insert, apart from NoIndent they look identical

So when looking at the help documentation for #Call and #Insert, apart from #Insert having the extra NoIndent attribute, they look identical, but they are not and the help docs dont elucidate their differences.

So does anyone know what their differences are?

TIA

#INSERT was the original, and always injected code at the current indent position. That’s why it has the NOINDENT option.

#CALL was added later, and is essentially the same as #INSERT,NOINDENT.

So why was #CALL added? It’s considered a convention now that #INSERT should be used to denote the generation of code by the referenced #GROUP, whereas #CALL is used only for execution of template code.

I find that distinction helpful, as I want the intent of my code to be as readable and clear as possible. Regardless, you can use both as you see fit.

1 Like

Isnt that supposed to be the other way around?

So I cant use #Call inside template prompts but I can use inserts

sheet,Hscroll
#Tab(‘&1 Overview’)
#Display(‘’)
#Button(‘Overview’),At(,175,12)
#Insert(%grpOverview)
#EndButton
#Button(‘Explorer Tools’),At(,175,12)
#Insert(%grpExplorerTools)
#EndButton
#EndTab
#Tab(‘&2 Include Files’)
#Insert(%grpTab2includefiles)
#EndTab
#Tab(‘&3 Inside Map Include Filenames’)
#Insert(%grpTab3InsideMapIncludeFiles)
#EndTab
#Tab(‘&4 Inside Map Module Prototypes’)
#Insert(%grpTab4InsideMapModulePrototypes)
#EndTab
#EndSheet

If I swap the above inserts with #Call the appgen complains.

As I mentioned, #INSERT existed first, so it’s used more often than it needs to be. I still use #INSERT within the #PROMPT area, as you’re suggesting. In a sense, I consider it as “generation of template code”, rather than “generation of Clarion code”. :wink:

Where I use #CALL is when I want to execute some template logic, and the called logic will not directly generate any code.

Don’t forget that there’s a third way to invoke a group–by using it in a template expression:

#SET(%MyVar, %MyGroup())

Alternatively, you could do that same thing using #CALL:

#CALL(%MyGroup), %MyVar

If your group had parameters, the alternate syntaxes vary accordingly:

#SET(%MyVar, %MyGroup(%Parm1, %Parm2))
#CALL(%MyGroup, %Parm1, %Parm2), %MyVar

I don’t believe you can use #INSERT to capture a return value.

2 Likes

and a sort of fourth way because it is an expression is inside ,WHERE()

#Tab('&1 Include Files'), Where(%DTR(%Tabs,'#Tab(''&1 Include Files'')'))

where %DTR is a #group that takes the parameters and sends them off to debugview and Returns %true

#Procedure(ClarionProc,'Clarion Procedure')
#Restrict,Where(%grpFirstProcedureIsTrue() )                                    #Call(%DT,%T,'#Restrict,Where(%grpFirstProcedureIsTrue()['& %grpFirstProcedureIsTrue() &'] )')
    #Accept                                                                     #Call(%DT,%T,'#Accept')
#EndRestrict                                                                    #Call(%DT,%T,'#EndRestrict')

In the above example the %DT group does not Return %True but the #Group %grpFirstProcedureIsTrue() does Return %True

I’ve been having to try code to see what is complained about and not, in the same way a Fuzzer would do this.

The Help shows #INSERT can return a value, but I searched the shipping templates and did not find any. I would guess it calls the same template library “thing” as #CALL so would work identically except NONDENT default.

Another way to get a kind of return value is passed by address *%Var

And when a CSV approach perhaps encapsulated with double quotes is employed for clarity to a single parameter Cstring passed by address, one starts to question if the single parameter is a single parameter for other parts of the template language like #RunDll.

#Group(%grpParseEquate,*%pIO1,*%pIO2)
#! This calls a procedure which passes a csv string back which is parsed into the two vars from
#! "WhenAccepted( %grpParseEquate(%EquateName,%EquateValue)"
#!
#Declare(%csvString)
#Declare(%commaPos)
#Declare(%csvStringLen)
#Set(%csvString,clip(%pIO1) &','& clip(%pIO2))
#RUNDLL('myrundll.dll', 'PROC3@FRsc',%csvString), release, win32
#Set(%commaPos,instring(',',%csvString,1,1) )
#Set(%csvStringLen,Len(Clip(%csvString)) )
#Set(%pIO1,Sub(%csvString,1,%commaPos-1) )
#Set(%pIO2,Sub(%csvString,%commaPos+1,%csvString - (%commaPos + 1) ) )