Kbase P83725: Frequently Asked Questions about ARGUMENTs, PARAMETERs, SHARED VARs and INCLUDEs
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  8/9/2004 |
|
Status: Unverified
GOAL:
Frequently Asked Questions about ARGUMENTs, PARAMETERs, SHARED VARs and INCLUDEs
FIX:
Here are answers to some common questions regarding PARAMETER and ARGUMENT passing among procedures and include files, and using SHARED VARIABLEs.
PERFORMANCE
===========
GLOBAL SHARED variables occupy memory space more or less permanently. (You can recover most of the space by setting the variable = "" or 0). NEW SHARED variables occupy memory space until their program terminates.
PARAMETERs occupy space on the stack, temporarily, then they are copied into the subroutine as local VARIABLES and popped off the stack. For INPUT-OUTPUT or OUTPUT PARAMETERS, when the subroutine finishes, the local variable is copied back onto the stack and the caller then copies the value from the stack into its variable.
So... a PARAMETER occupies space only while the SUBROUTINE is active. A NEW SHARED variable occupies space while the CALLER is active.
Therefore, if you are passing a complex expression to a subroutine it is better to pass it as a parameter than to copy it to a shared variable.
However, if you are passing a variable to a subroutine, and that variable is already occupying storage for the life of the caller, it may be just as easy and somewhat more efficient to simply make that variable NEW SHARED and not use parameters.
A program VARIABLE whose value is changed during a transaction has that change noted in the local before image file (.lbi) on disk. To eliminate this performance impact, define the VARIABLE as NO-UNDO, or update its value outside the scope of the transaction. Changes to the value of a PARAMETER are not captured on disk, regardless of the transaction status. But...in all but extreme cases, the benefits of using PARAMETERS to get good structured code outweigh any
considerations of the amount of storage saved or used.
PASSING A FILE, FIELD, OR INDEX NAME
====================================
SESSION COMPILES
----------------
You can, under PADS, 4GL/RDBMS, QUERY or QUERY/REPORT licenses, use session compiles to execute procedures where the parameter being passed to a procedure represents a file, field, or index name. Use the brace-integer-brace syntax in the called procedure. The procedure "proc1.p" can be pre-compiled; "proc1a.p" cannot be.
/* proc1.p */
DEF VAR a AS CHAR FORMAT "X(20)".
DEF VAR b AS CHAR FORMAT "X(20)".
DEF VAR c as CHAR FORMAT "X(20)".
SET a HELP "Enter file name to query" LABEL "File"
b HELP "Enter selection criteria" LABEL "Where"
c HELP "Enter index sort to use" LABEL "Index".
RUN proc1a.p value(a) value(b) value(c) "'AD HOC QUERY'" "2 COLUMNS".
/* proc1a.p */
FOR EACH {1} WHERE {2} BY {3}:
DISPLAY {1} WITH TITLE {4} {5}.
END.
PRE-COMPILED PROCEDURES
-----------------------
You can use the argument passing of include files as well. To provide as much flexibility as the above example requires more statements in the main-line procedure, however, by doing so you can provide an application that can be precompiled. The CHOOSE and SCROLL procedure library provides samples of these
kinds of browse routines.
The named arguments (&file and &sort in this example) do not need to be defined independently of the first time they are used. The character string that follows the "&" does not have to be the name of a dictionary element.
DEF VAR a AS CHAR FORMAT "X(20)".
DEF VAR b AS CHAR FORMAT "X(20)".
SET a HELP "Enter file name to query" LABEL "File"
b HELP "Enter index sort to use" LABEL "Index".
IF a = "customer" AND b = "name" THEN
{proc1a.i &file="customer" &sort="name" &fr="2 COLUMNS"}
ELSE IF a = "customer" AND b = "zip" THEN
{proc1a.i &file="customer" &sort="zip" &fr=&quo.t;3 COLUMNS"}.
/* NOTE: above you would need to code for all possible
combinations that you wanted the application to support */
/* proc1a.i */
FOR EACH {&file} BY {&sort}:
DISPLAY {&file} WITH {&fr}.
END.
To pass quoted strings to a syntax location that itself requires quotes, you can either quote the quote, by having one for the regular syntax, one quote character for the literal quotation mark, and one quote character to identify the literal, or you can use a single quote character.
/* aaa.p */
def var ws-balance as int.
{aaa2.i &ws-labelx = """Normal Hours"""}.
/* bbb.p */
def var ws-balance as int.
{aaa2.i &ws-labelx = "'Overtime Hours'"}.
/* aaa2.i */
form ws-balance colon 12 label {&ws-labelx} with frame x.
set ws-balance with frame x.
The examples above will allow you to pass an argument to an include file where the syntax of the statement using the argument requires a quoted string and the quotes around the string. You won't be able to prompt for the value, however. It has to be a value known to the compiler at compile time (vs. execution time), that is, hard-coded.
Include files can be nested inside each other, and you can use the name of an include file as an argument to another include file. (The sub-procedure syntax would have {{1}} in it.)
COMMON PROBLEMS
===============
Common problems that occur when using SHARED VARIABLES, PARAMETERS,
and ARGUMENTS include:
- Getting error messages on memory. Variables and parameters are kept in the memory space allocated by the -l local buffer size startup option. They are also affected by the -s stack size. Increasing these will often correct memory errors.
- Passing a parameter to a procedure from the startup of PROGRESS. The PROGRESS startup from the operating system will only accept as parameters those startup options which control the configuration, memory management, format options, and database connections of PROGRESS itself (_progres, _mprosrv). Data used by the application must be made available to the application either via a disk file, a dictionary record, or an operating system environment variable setting. For example, to perform a batch compile, use the operating system directory listing utility (ls, dir, files) and direct the listing output to a file. Then use that file as the input to PROGRESS processing, e.g.,
UNIX SILENT ls *.p > compile.lst.
DEF WORKFILE prog-list
FIELD prog-name AS CHAR FORMAT "X(30)".
INPUT FROM compile.lst.
REPEAT:
CREATE prog-list.
IMPORT prog-name.
COMPILE VALUE(prog-name) SAVE.
END.
See the Language Reference guide under
- {} Argument Reference (p. 12)
- {} Include Files (p. 15)
- COMPILE
- DEFINE PARAMETER
- DEFINE VARIABLE
- RUN
Progress Software Technical Support Note # 11750.