Kbase 11750: ARGUMENTs, PARAMETERs, SHARED VARs, INCLUDE common questions
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  5/10/1998 |
|
ARGUMENTs, PARAMETERs, SHARED VARs, INCLUDE common questions
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="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