Order of include file parameters influence DEFINED() value

Posted by Patrick Tingen on 15-Jul-2019 12:19

In one of our include files I came across some interesting behaviour.

First, create the following include file:

/* c:\temp\1.i */
&IF DEFINED(myParam) = 0 &THEN
  MESSAGE 'Not defined' VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
&ELSE
  MESSAGE 'Defined' VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
&ENDIF

Then run this:

/* 1 */ {c:\temp\1.i            &myParam } /* defined */
/* 2 */ {c:\temp\1.i &abc=1     &myParam } /* defined */
/* 3 */ {c:\temp\1.i &myParam=* &abc     } /* defined */
/* 4 */ {c:\temp\1.i &myParam=* &abc=1   } /* defined */
/* 5 */ {c:\temp\1.i &abc       &myParam } /* not defined */
/* 6 */ {c:\temp\1.i &myParam   &abc     } /* not defined */
/* 7 */ {c:\temp\1.i &myParam   &abc=1   } /* not defined */

I already added the outcome, but what strikes me are the cases where it says "Not Defined". It looks like the order of the parameters influence the value of DEFINED.

Case #1 - #4 are as expected. Even if the parameter has no value, it /is/ defined.  
Starting at #5 things are going downhill for me. Why is the parameter "Not defined" there?

Is this a bug in the compiler or is this expected (and documented somewhere)?

Tested in 10.1C / 11.2 / 11.7

All Replies

Posted by cverbiest on 15-Jul-2019 15:45

If I read documentation.progress.com/.../index.html correctly it's a bug that progress allows named parameters without equility sign.

The syntax diagram allows for either a list of positional parameters or a list of name/value pairs.

Posted by Patrick Tingen on 16-Jul-2019 06:03

Hmm, yes, if you look at the structure of an include file:

{ include-file
[ argument ... | {&argument-name = "argument-value" } ... ] }

It looks as if it should not be allowed to pass in a parameter without a value, otherwise the description should have read:

{ include-file
[ argument ... | {&argument-name [ = "argument-value" ] } ... ] }

So its behaviour is not a bug, but the fact that the compiler accepts it, is.

BTW, these 'tips' on the page you linked should really be removed:

  • When you have a base procedure and want to make several copies of it, changing it slightly each time, use include files with parameters. For example, at times you might only want to change the name of some files or fields used by the procedure.

  • Instead of maintaining duplicate source files, create a single include file with the variable portions (such as the names of files and fields) replaced by {1}, {2}, etc. Then each procedure you write can use that include file, passing file and field names as arguments.

One should really not be doing this anymore now. 

Posted by frank.meulblok on 16-Jul-2019 08:35

And apart from the notes that are nowadays irrelevant (Sequent platform has not been supported for how long exactly?) or bad practice, the one that really identifies current behavior as a bug is of course the first one:

"You can pass a series of positional arguments or a series of named arguments to an include file, but you cannot pass a combination of positional and named arguments to an include file."

So in the example, case 2,3 and 7 should raise a compile-time error.

And in cases 1,5 and 6, I'd say what you *should* see is that myParam is not defined as a preprocessor name, and the positional arguments resolve to the literal string "&myParam" -> without the "=" those don't follow the syntax for named arguments so they should not be parsed as such.

Posted by Patrick Tingen on 17-Jul-2019 07:58

I don't think that a parameter whose name starts with an ampersand, but has no value identifies as an unnamed parameter.

Try this:

/* c:\temp\1.i 
*/
MESSAGE 'Param 1: {1}'
  SKIP 'Param 2: {&hello}'
  VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

then run:

{c:\temp\1.i hello }
{c:\temp\1.i &hello }

You will see:

/* message 1 */
Param 1: hello 
Param 2: 

/* message 2 */
Param 1: 
Param 2: 

So the parameter &hello is not recognized as an unnamed parameter. 

This thread is closed