Executing Other Maintain Procedures

In this section:

You can call one Maintain procedure from another with the CALL command. Maintain procedure here means any procedure of Maintain language commands. CALL simplifies the process of modularizing an application. Software designed as a group of related modules tends to be easier to debug, easier to maintain, and lends itself to being reused by other applications, all of which increase your productivity.

CALL also makes it easy to partition an application, deploying each type of logic on the platform on which it will run most effectively.

The following diagram illustrates how to describe the relationship between called and calling procedures. It describes a sequence of five procedures from the perspective of the middle procedure, which is named C.

Note: A root procedure is also called the starting procedure.

diagram illustrates how to relationships between called calling


Top of page

x
Calling a Maintain Procedure on a Different Server

If parent and child Maintain procedures reside on different servers, you identify the location of the child procedure in a deployment scenario in the Maintain Development Environment. At deployment time, the Maintain Development Environment automatically informs the parent procedure of the location of the child procedure by supplying the AT server phrase in the CALL command. Do not code the AT server phrase yourself unless the parent procedure is not part of your project.

If the parent procedure is not a native project component, code the AT server phrase yourself in the CALL command of the parent procedure (or use the Language Wizard to generate the CALL command) to identify the location of the child procedure.



Example: Calling the EmpUpdat Procedure on a Different Server

Consider the EmpUpdat procedure:

MAINTAIN FILE Employee
FOR ALL NEXT Emp_ID INTO EmpStack;
.
.
.
CALL NewClass;
.
.
.
END

This calls the NewClass procedure that is deployed on the EducServ WebFOCUS Server:

MAINTAIN
.
.
.
END

In this example, EmpUpdat is the parent procedure and NewClass is the child procedure. When the child procedure, and any procedures that it has invoked, have finished executing, control returns to the parent.


Top of page

x
Passing Variables Between Procedures

All user variables (both stacks and simple, or scalar, variables) are global to a function or procedure, but not global to the project. In other words, to protect them from unintended changes in other parts of a project, you cannot directly reference a variable outside of the procedure in which it is found (with the exception of the FocError transaction variable). However, you can access the variable data in other procedures, simply by passing it as an argument from one procedure to another.

To pass variables as arguments, you only need to name them in the CALL command, and then again in the corresponding MAINTAIN command, using the FROM phrase for input arguments and INTO phrase for output arguments. Some variable attributes must match in the CALL and MAINTAIN commands:

Other attributes need not match:

After you have passed a variable to a child procedure, you need to define it in that procedure. How you define it depends upon the type of variable:

After a variable has been defined in the child procedure, its data becomes available. If you refer to stack cells that were not assigned values in the parent procedure, they are assigned default values (such as spaces or zeros) in the child procedure, and a message is displayed warning that they have not been explicitly assigned any values.

When the child procedure returns control back to the parent procedure, the values of stacks and simple variables specified as output arguments are passed back to the parent. The values of stacks and simple variables specified only as input arguments are not passed back.



Example: Passing Data Between Maintain Procedures

This procedure

MAINTAIN FILE Employee
FOR ALL NEXT Emp_ID INTO EmpStack;
.
.
.
CALL NewClass FROM EmpStack CourseStack INTO CourseStack;
.
.
.
END

calls the NEWCLASS procedure:

MAINTAIN FROM StudentStack CourseStack INTO CourseStack
.
.
.
END

EmpStack and CourseStack in the parent procedure correspond to StudentStack and CourseStack in the child procedure.


Top of page

x
Accessing Data Sources in the Child Procedure

If a child procedure accesses a data source, whether retrieving or writing records, you must specify the data source in the MAINTAIN command. This is done the same way as for a stand-alone procedure. For example, the procedure below specifies the Employee and EducFile data sources:

MAINTAIN FILES Employee AND EducFile FROM StuStk INTO CoursStk
.
.
.
END

Top of page

x
Data Source Position in Child Procedures

Each Maintain procedure tracks its own position in the data source. When you first call a procedure, Maintain positions you at the beginning of each segment in each data source accessed within that procedure. After navigating through a data source, you can reposition to the beginning of a segment by issuing the REPOSITION command. The data source positions are independent of the positions established in other procedures.

When a child procedure returns control to its parent, by default it clears its data source positions. You can specify that it retain its positions for future calls by using the KEEP option, as described in Optimizing Performance: Data Continuity and Memory Management.


Top of page

x
Advantages of Modularizing Source Code Using CALL

Modularizing source code into several procedures has many advantages. One benefit is that you can use multiple procedures, run using the CALL command, to share common source code among many developers, speeding up both development and maintenance time. For example, a generalized error message display procedure could be used by all WebFOCUS Maintain developers. After passing a message to the generalized procedure, the procedure would handle message display. The developers do not need to worry about how to display the message, and the error messages will always look consistent to end users.

Another advantage of modular design is that you can remove infrequently-run source code from a procedure and move it into its own procedure. This reduces the size of the original procedure, simplifying its logic, making maintenance easier, and using less memory if the new procedure is not called.


Top of page

x
Optimizing Performance: Data Continuity and Memory Management

By default, when you terminate a child procedure, Maintain clears its data from memory to save space. You can optimize your application performance by specifying, each time you terminate a child procedure, how you want Maintain to handle the procedure data. You have two options, based on how often you will call a given procedure over the course of an application. If you will call the procedure:

For more information about transactions spanning procedures, see Ensuring Transaction Integrity in the Developing WebFOCUS Maintain Applications manual.

You can specify how a procedure will handle its data in memory by terminating it with the GOTO END command qualified with the appropriate memory-management phrase. The syntax is

GOTO END [KEEP|RESET];

where:

KEEP

Terminates the procedure, but keeps its data, the values of its variables and data source position pointers, in memory. It remains in memory through the next invocation, or (if it is not called again) until the application terminates. The procedure does not issue an implied COMMIT command to close an open logical transaction.

RESET

Terminates the procedure, clears its data from memory, and issues an implied COMMIT command to close an open logical transaction. RESET is the default value.

You can use both options in the same procedure. For example, when you are ready to end a child procedure, you could evaluate what logic the procedure will need to perform when it is next called and then branch accordingly either to keep data in memory, saving time and providing data continuity, or else to clear data from memory to conserve space.


WebFOCUS