Kbase 13554: INCLUDE FILE PARAMETERS - do not mix NAMED and UNNAMED
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  10/05/1998 |
|
INCLUDE FILE PARAMETERS - do not mix NAMED and UNNAMED
When using include file references the compiler does not like it when
you combine named and unnamed parameters within one reference. The
example below illustrates the problem and its solution.
The files in Example 1 show how you might try to use both named
and unnamed parameters with include files.
EXAMPLE 1:
/* main.p */
DEF VAR x AS CHAR.
x = "WHERE customer.cust-num = 4".
RUN t2.p x.
/* t2.p */
{t2.i "{1}" &find="zrbr.fnd"}
/* t2.i */
{{&find} &finder="FIRST" &where="{1}"}.
/* zrbr.fnd */
FIND {&finder} customer {&where} NO-LOCK NO-ERROR.
DISPLAY customer.name.
When you try to run main.p, error 293 results:
** "&finder="FIRST"" not found (293).
This is because when the compiler gets to t2.p, it sees the
reference to parameter {1} (an unnamed parameter) along with the
reference to &find (a named parameter). Because the unnamed parameter
is encountered first, the compiler assumes that all parameters will
be similarly unnamed and ignores the named one.
As a consequence, when the compiler gets to t2.i, it has done away
with the &find parameter from t2.p. This means that the &find in
t2.i is also ignored. As it happens, &find has been designated to
hold the name of the file to be included in t2.i, so when the compiler
ignores it, the next thing it does is intrepret the next string
as the file name. In this example, that string is "&finder="FIRST"".
Naturally, such a file does not exist, so the error message results:
"&finder="FIRST"" not found (293).
The way around this problem is to rewrite the example so that it uses
either all unnamed parameters or all named ones. Example 2 shows how
it could be rewritten to use only unnamed parameters.
EXAMPLE 2:
/* main.p */
DEF VAR x AS CHAR.
x = "WHERE customer.cust-num = 4".
RUN t2.p x.
/* t2.p */
{t2.i "{1}" "zrbr.fnd"}
/* t2.i */
{{2} "FIRST" "{1}"}
/* zrbr.fnd */
FIND {1} customer {2} NO-LOCK NO-ERROR.
DISPLAY customer.name.
Example 3 shows how the same thing can be accomplished by using only
named parameters.
EXAMPLE 3:
/* main.p */
DEF VAR x AS CHAR.
x = "WHERE customer.cust-num = 4".
RUN t2.p x.
/* t2.p */
{t2.i &where="{1}" &find="zrbr.fnd"}
/* t2.i */
{{&find} &finder="FIRST" &which="{&where}"}
/* zrbr.fnd */
FIND {&finder} customer {&which} NO-LOCK NO-ERROR.
DISPLAY customer.name.
Version 7 compiler's preprocessor enforces the above rule very
strictly. A new compiler option, PREPROCESS, is available to see the
substitutions.
EXAMPLE 4:
/* test1.p */
{test1.i "state"}
/* test1.i */
{test2.i &file = "{1}"}
/* test2.i */
FOR EACH {&file}:
DISPLAY {&file}.
END.
Executing:
COMPILE test1.p PREPROCESS test2.p .
will cause test2.p to contain:
FOR EACH state:
DISPLAY state.
END.
Progress Software Technical Support Note # 13554